/
Автор: Ибрагим Доган
Теги: электроника радиотехника радиостанция микроконтроллеры цифровая электроника
ISBN: 978-3-89576-481-3
Год: 2021
Текст
books
Raspberry Pi Pico для
радиолюбителей
Программирование и создание утилит,
инструментов и приборов для
радиолюбительской станции на основе RPi
Pico.
Доган Ибрагим, G7SCU
Доган Ибрагим Raspberry Pi Pico для
радиолюбителей
Программирование и создание утилит, инструментов и приборов для
радиолюбительской станции на основе RPi Pico.
●
Доган Ибрагим, G7SCU
Contents
Предисловие . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Глава 1 • Аппаратное обеспечение Raspberry Pi Pico . . . . . . . . . . . . . . . . . . . . . 12
1.1 Обзор . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . 12
1.2 Аппаратный модуль Pico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3 Сравнение с Arduino UNO. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.4 Условия эксплуатации и питание Pico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.5 Распиновка микроконтроллера RP2040 и модуля Pico . . . . . . . . . . . . . . . . . . . . 16
1.6 Other RP2040 microcontroller-based boards . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.6.1 Adafruit Feather RP2040 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.6.2 Adafruit ItsyBitsy RP2040 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.6.3 Pimoroni PicoSystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.6.4 Arduino Nano RP2040 Connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.6.5 SparkFun Thing Plus RP2040 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.6.6 Pimoroni Pico Explorer Base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.6.7 SparkFun MicroMod RP2040 Processor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.6.8 SparkFun Pro Micro RP2040 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.6.9 Pico RGB Keypad Base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.6.10 Pico Omnibus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.6.11 Pimoroni Pico VGA Demo Base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1.6.12 Tiny 2040 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Глава 2 • Программирование Raspberry Pi Pico . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.1 Обзор . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.2 Установка MicroPython на Pico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.2.1 Использование Raspberry Pi 4 для установки MicroPython на Pico . . . . . . . . 27
2.2.2 Использование ПК (Windows 10) для установки MicroPython на Pico . . . . . . 34
Глава 3 • Простые программы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.1 Обзор . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.2 Примеры . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.2.1 Среднее значение двух чисел, считанных с клавиатуры . . . . . . . . . . . . . . . . 38
3.2.2 Среднее значение 10 чисел, считанных с клавиатуры . . . . . . . . . . . . . . . . . . 38
3.2.3 Площадь поверхности цилиндра . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.2.4 Перевод ºC в ºF. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
●5
Raspberry Pi Pico for Radio Amateurs
3.2.5 Площадь поверхности и объем цилиндра – пользовательская функция. . . . . . 41
3.2.6 Таблица квадратов чисел . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.2.7 Таблица тригонометрических синусов. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.2.8 Таблица тригонометрических синусов, косинусов и тангенсов . . . . . . . . . . . 43
3.2.9 Тригонометрическая функция требуемого угла . . . . . . . . . . . . . . . . . . . . . . . 43
3.2.10 Слова в обратном порядке . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.2.11 Калькулятор . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.2.12 Игральные кости . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.2.13 Сортировка списков . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.2.14 Обработка файлов — запись . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.2.15 Обработка файлов — чтение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.2.16 Квадраты и кубы чисел . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
3.2.17 Таблица умножения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
3.2.18 Четные или нечетные? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.2.19 Двоичная, восьмеричная и шестнадцатеричная системы счисления . . . . . . . 49
3.2.20 Сложение двух матриц . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
3.2.21 Фигуры . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Глава 4 • Программы для любительской радиосвязи — только программы . . . 53
4.1 Обзор . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53
4.2 Примеры . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.2.1 Идентификатор цветовой кодировки 4-полосных резисторов . . . . . . . . . . . . 53
4.2.2 Идентификатор цветовой . . . . включая малые резисторы . . . . . . . . . . . . . . 55
4.2.3 Делитель напряжения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
4.2.4 Резистивный аттенюатор — равные сопротивления источника и нагрузки . . . 59
4.2.5 Резистивный аттенюатор — неравные сопротивления источника и нагрузки . 63
4.2.6 Стабилизатор напряжения на основе стабилитрона . . . . . . . . . . . . . . . . . . . 65
4.2.7 Частотная характеристика RC-цепи . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
4.2.8 Резонанс в последовательных RLC-цепях . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.2.9 Расчет индуктивности однослойной катушки . . . . . . . . . . . . . . . . . . . . . . . . 74
4.2.10 Изготовление однослойной катушки требуемой индуктивности . . . . . . . . . . 76
4.2.11 Смещение делителя напряжения на биполярном транзисторе . . . . . . . . . . . 77
4.2.12. Схемы усилителя на биполярном транзисторе с общим эмиттером . . . . . . . 80
●6
4.2.13 Проектирование активных фильтров нижних частот . . . . . . . . . . . . . . . . . . 84
4.2.14 Длина четвертьволновой вертикальной антенны. . . . . . . . . . . . . . . . . . . . . 89
4.2.15 Генератор на микросхеме 555 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
4.2. Согласование импеданса. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Глава 5 • Простые аппаратные проекты . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
5.1 Обзор . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
5.2 Проект 1: Мигание встроенного светодиода. . . . . . . . . . . . . . . . . . . . . . . . . . . 99
5.3 Проект 2: Внешний мигающий светодиод . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
5.4 Проект 3: Изменение частоты мигания светодиода с помощью прерываний
. . 104
5.5 Проект 4: Двоичные счетные светодиоды . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
5.6 Использование параллельных ЖК-дисплеев . . . . . . . . . . . . . . . . . . . . . . . . . 112
5.7 Проект 5: Функции ЖК-дисплея — отображение текста . . . . . . . . . . . . . . . . . 115
5.8 Проект 6: Счетчик секунд – параллельный ЖК-дисплей. . . . . . . . . . . . . . . . . 120
5.9 Использование ЖК-дисплеев с интерфейсом I2C . . . . . . . . . . . . . . . . . . . . . . 121
5.10 Проект 7: Счетчик секунд с ЖК-дисплеем I2C . . . . . . . . . . . . . . . . . . . . . . . 121
Глава 6 • Проекты по радиолюбительству на аппаратном обеспечении. . . . . . 125
6.1 Обзор . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
6.2 Проект 1: Управление питанием станции (вкл/выкл) . . . . . . . . . . . . . . . . . . . . 125
6.3 Проект 2: Станционные часы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
6.4 Проект 3: Температура и влажность на станции . . . . . . . . . . . . . . . . . . . . . . . 134
6.5 Проект 4: Географические координаты станции . . . . . . . . . . . . . . . . . . . . . . . 137
6.6 Генерация сигналов – с использованием программного обеспечения. . . . . . . . . 144
6.6.1 Проект 5: Генерация прямоугольного сигнала с амплитудой менее +3,3 В. . . 145
6.6.2 Проект 6: Генерация фиксированных напряжений . . . .
. . . . . . . . . . . . . . . . 150
6.6.3 Проект 7: Генерация пилообразного сигнала. . . . . . . . . . . . . . . . . . . . . . . . . 152
6.6.4 Проект 8: Генерация сигнала треугольной формы . . . . . . . . . . . . . . . . . . . . . 154
6.6.5 Проект 9: Произвольная периодическая форма сигнала . . . . . . . . . . . . . . . . 156
6.6.6 Проект 10: Генерация синусоидального сигнала . . . . . . . . . . . . . . . . . . . . . . 158
6.6.7 Проект 11: Генерация синусоидального сигнала прерываниямы таймера . . . . 161
6.7 Генерация сигналов — с использованием аппаратного обеспечения . . . . . . . . . 163
6.7.1 Проект 12: Генератор сигналов с фиксированной частотой . . . . . . . . . . . . . . . 164
●7
Raspberry Pi Pico for Radio Amateurs
6.7.2 Проект 13: Генерация сигналов с включенным вводом частоты с помощью
клавиатуры и индикации на ЖК-дисплее . . . . . . . . . . . . . . . . . . . . . . . . . . . . .171
6.8 Проект 14: Частотомер . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
6.9 Вольтметр – Амперметр – Омметр – Измеритель емкости . . . . . . . . . . . . . . . . 187
6.9.1 Проект 15: Вольтметр . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ..188
6.9.2 Проект 16: Амперметр . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
6.9.3 Проект 17: Омметр . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .190
6.9.4 Проект 18: Измеритель емкости . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
6.10 Проект 19: Измеритель мощности ВЧ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
6.10.1 Радиочастотные аттенюаторы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
6.10.2 дБ, дБм и Вт? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .204
6.11 Проект 20: Использование панели управления RadioStation . . . . . . . . . . . . 206
6.12 Тренажёры по азбуке Морзе . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
6.12.1 Проект 21: Символы, вводимые пользователем . . . . . . . . . . . . . . . . . . . . . 217
6.12.2 Проект 22: Отправка случайно сгенерированных символов. . . . . . . . . . . . . 222
6.12.3 Проект 23: Установ. скорости Морзе с помощью ЖК-дисплея и энкодера . . .225
6.13 Проект 24: Релейный секвенсор с временными задержками . . . . . . . . . . . . . .232
6.14 Проект 25: FM-радио с Raspberry Pi Pico . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
6.14.1 Проект 26: Модифицированное FM-радио – увеличение уровня выходного
сигнала – подключение громкоговорителя. . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . 244
6.14.2 Проект 27: FM-радио с использованием ЖК-дисплея и внешних кнопок . . . 246
6.14.3 Проект 28: FM-радио с использованием ЖК-дисплея и поворотного энкодера 251
6.15 Проект 29: Измерение частоты и рабочего цикла сигнала ШИМ –
экранное изображение. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
6.16 Проект 30: Измерение частоты и рабочего цикла сигнала ШИМ –
ЖК-дисплей . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
6.17 Bluetooth-интерфейс Raspberry Pi Pico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
6.17.1 Проект 31: Управление светодиодом со смартфона с помощью Bluetooth . . . 260
6.18 Проект 32: Безопасность станции. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
6.19 Проект 33: Генерация точных прямоугольных сигналов с использованием
конечных автоматов Raspberry Pi Pico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
6.20 Проект 34: Использование Wi-Fi с Raspberry Pi Pico –
управление светодиодом со смартфона . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .271
●8
6.21 Проект 35: Модуль аудиоусилителя с энкодером для регулировки гром.ко
. сти 279
6.22 Проект 36: Декодер Морзе . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
285
6.23 Raspberry Pi Pico RTL-SDR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
6.24 Проект 37: Использование пары передатчик/приемник FS1000A 433 МГц . . . 298
Глава 7 • Автоматический запуск программы после загрузки Raspberry Pi Pico. . . . 304
Приложение. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
Детали, используемые в проектах . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
●9
Preface
Предисловие
В последние годы произошли значительные изменения в оборудовании, обычно используемом
радиолюбителями. Хотя большая часть классического КВ-оборудования и мобильной техники
по-прежнему используется значительным числом радиолюбителей, мы наблюдаем рост
популярности компьютеров и цифровых технологий среди радиолюбителей. На заре цифровой
связи радиолюбители использовали персональные компьютеры для общения друг с другом. К
сожалению, эти ПК имели недостаток в виде высокой стоимости и громоздкости. Однако
сегодня любой может купить компьютер Raspberry Pi Pico за 5 евро и создать множество
интересных проектов в области любительской радиосвязи, используя это устройство, которое
меньше кредитной карты.
Несколько авторов выпустили книги и опубликовали проекты по внедрению Arduino и
Raspberry Pi в проекты для радиолюбителей. Raspberry Pi Pico является практичной
альтернативой Arduino благодаря своей низкой стоимости, скорости, вычислительной
мощности, большому объему памяти, множеству входных и выходных портов, поддержке
периферийного оборудования и простоте программирования. Raspberry Pi Pico не имеет
операционной системы, что делает его удобным в использовании в качестве
универсального микроконтроллера. Благодаря этим особенностям, RPi Pico хорошо
подходит для использования в качестве «готового» компьютера в проектах для
радиолюбителей.
Эта книга преследует три цели: во-первых, она призвана обучить начинающих основам работы
и функциям Raspberry Pi Pico. Во-вторых, в ней представлены программные проекты, которые
будут интересны радиолюбителям. Наконец, приводится множество аппаратных проектов,
использующих Raspberry Pi Pico в сочетании с языком программирования Python 3. Хотя эти
проекты носят широкий характер, они были выбраны как интересные и полезные для
радиолюбителей.
Все проекты, использованные в книге, были протестированы и полностью работоспособны.
Проекты описаны с помощью блок-схем, принципиальных схем и полных листингов
программ. Листинги программ описаны подробно, и читатели смогут легко модифицировать
проекты под свои нужды.
Надеюсь, вам понравится книга, и вы найдете представленные проекты
интересными и полезными.
Профессор Доган Ибрагим, G7SCU, Лондон, 2021
● 11
Raspberry Pi Pico for Radio Amateurs
Глава 1 • Аппаратное обеспечение Raspberry Pi Pico
1.1 Обзор
Raspberry Pi Pico — это одноплатный микроконтроллерный модуль, разработанный фондом
Raspberry Pi Foundation. Модуль основан на микроконтроллере RP2040. В этой главе мы
подробно рассмотрим аппаратные характеристики микроконтроллерного модуля Raspberry Pi
Pico. В дальнейшем мы будем называть этот микроконтроллерный модуль сокращенно «Pico».
1.2 Аппаратный модуль Pico
Pico — это очень недорогой микроконтроллерный модуль стоимостью 4 доллара, основанный
на микроконтроллере RP2040 с двумя процессорами Cortex-M0+. На рис. 1.1 показан вид
спереди аппаратного модуля Pico, представляющего собой небольшую плату. В центре платы
расположен крошечный микроконтроллер RP2040 размером 7 × 7 мм в корпусе QFN-56. По
краям платы расположены золотистые металлические контакты GPIO (General Input Output) с
отверстиями. Необходимо припаять контакты к этим отверстиям для удобного подключения
внешних устройств к плате. Отверстия промаркированы, начиная с цифры 1 в верхнем левом
углу платы, и номера увеличиваются вниз до цифры 40, которая находится в верхнем правом
углу платы. Плата совместима с макетными платами (т.е. расстояние между контактами
составляет 0,1 дюйма), и после пайки контактов плату можно подключить к макетной плате
для удобного соединения с контактами GPIO с помощью перемычек. Рядом с этими
отверстиями вы увидите выпуклые круглые вырезы, которые можно устанавливать поверх
других модулей без установки каких-либо физических контактов.
Рис. 1.1: Вид спереди аппаратного модуля Pico.
На одном краю платы расположен порт micro-USB B для подачи питания на плату и для ее
программирования. Рядом с портом USB находится встроенный светодиод, который можно
использовать во время разработки программ. Рядом с этим светодиодом находится кнопка
BOOTSEL, которая используется во время программирования микроконтроллера, как мы
увидим в следующих главах. На другом краю платы, рядом с логотипом Raspberry Pi,
расположены три разъема, используемые для отладки ваших программ.
Рис. 1.2 показывает вид сзади аппаратного модуля Pico. Здесь все контакты GPIO
обозначены буквами и цифрами. Вы заметите следующие типы букв и цифр:
● 12
Chapter 1 • Raspberry Pi Pico Hardware
GND
AGND
3V3
GP0 – GP22
GP26_A0 – GP28_A2
ADC_VREF
TP1 – TP6
SWDIO, GND, SWCLK
RUN
—
земля источника питания (цифровая земля)
—
земля источника питания (аналоговая земля)
—
+3,3 В питания (выход)
—
цифровые GPIO
—
аналоговые входы
—
опорное напряжение АЦП
—
контрольные точки
—
интерфейс отладки
— пин RUN по умолчанию. Подключите LOW
для сброса RP2040
3V3_EN
— пин по умолчанию включает питание +3,3 В
VSYS
— входное напряжение (от 1,8 В до 5,5 В), используемое встроенным
импульсным источником питания (SMPS) +3,3 В для платы
VBUS
—
входное напряжение micro-USB (+5 В)
Рис. 1.2: Вид сзади аппаратного модуля Pico.
Некоторые контакты GPIO используются для внутренних функций платы. К ним относятся:
GP29
GP25
GP24
GP23
(input)
(output)
(input)
(output)
—
—
—
—
Используется в режиме АЦП (АЦП3) для измерения VSYS/3
подключен к встроенному пользовательскому светодиоду
VBUS-датчик: высокий уровень, если VBUS присутствует, в
противном случае низкий уровень
Управляет выводом энергосбережения встроенного импульсного
источника питания
Технические характеристики аппаратного модуля Pico следующие:
•
•
•
•
•
•
•
•
•
32-разрядный двухъядерный процессор RP2040 Cortex-M0+ с частотой 133 МГц
2 МБ флэш-памяти Q-SPI
264 Кбайт памяти SRAM
26 пинов GPIO (совместимых с +3,3 В)
с3 × 12-битных вывода АЦП
порт отладки по последовательному интерфейсу (SWD)
порт Micro-USB (USB 1.1) для питания (+5 В) и передачи данных (программирования)
2 × UART, 2 x I2C, 2 x SPI интерфейса шины
16 × каналов ШИМ
● 13
Raspberry Pi Pico for Radio Amateurs
•
•
•
•
•
1 × Таймер (с 4 будильниками), 1 × Счетчик реального времени
встроенный датчик температуры
встроенный светодиод (на порту GP25)
программирование на MicroPython, C, C++
программирование методом перетаскивания с использованием накопителей через USB
Аппаратные выводы GPIO платы Pico совместимы с напряжением +3,3 В, поэтому важно
соблюдать осторожность и не превышать это напряжение при подключении внешних устройств к
выводам GPIO. Для подключения устройств с выходами +5 В к выводам GPIO платы Pico
необходимо использовать логические преобразователи +5 В в +3,3 В или резистивные делители
напряжения.
На рис. 1.3 показана резистивная схема делителя напряжения, которую можно использовать для
понижения напряжения с +5 В до +3,3 В. Модуль логического преобразователя показан на рис. 1.4.
Этот модуль можно использовать для подключения выводов Pico к устройствам с напряжением
+5 В. Подключите выводы GND к земле, а выводы HV и LV — к +5 В и +3,3 В соответственно.
Используйте выводы TXI-TXO для подключения выходов +3,3 В платы Pico к устройствам с
входным напряжением +5 В. Аналогичным образом, используйте контакты RXI-RXO для
подключения устройств с выходным напряжением +5 В к входным контактам +3,3 В пикосекунды.
Рис. 1.3: Делитель напряжения.
Рис. 1.4: Модуль логического преобразователя.
1.3 Сравнение с Arduino UNO
Arduino UNO — одна из самых популярных плат разработки микроконтроллеров,
используемая студентами, практикующими инженерами и любителями. Как Arduino UNO, так и
модуль Raspberry Pi Pico являются микроконтроллерами без операционных систем. В таблице
1.1 приведено сравнение Raspberry Pi Pico с Arduino UNO.
● 14
Chapter 1 • Raspberry Pi Pico Hardware
Из этой таблицы видно, что Pico значительно быстрее, чем Arduino UNO, имеет больший
объем флэш-памяти и памяти данных, больше цифровых входных и выходных контактов и
встроенный датчик температуры. Arduino UNO работает при напряжении +5 В, и его контакты
GPIO совместимы с напряжением +5 В. К преимуществам Arduino UNO относятся встроенная
память EEPROM и шестиканальный АЦП вместо трех, как у Pico.
Feature
Raspberry Pi Pico
Arduino UNO
Microcontroller
RP2040
Atmega328P
Core and bits
Dual core, 32-bits, Cortex-M0+
Single-core 8-bits
RAM
264 Kbyte
2 KByte
Flash
2 MByte
32 KByte
CPU speed
48 MHZ to 133 MHz
16 MHz
EEPROM
None
1 KByte
Power input
+5 V through USB port
+5 V through USB port
Alternative power
2–5 V via VSYS pin
7–12 V
MCU operating voltage
+3.3 V
+5 V
GPIO count
26
20
ADC count
3
6
Hardware UART
2
1
Hardware I2C
2
1
Hardware SPI
2
1
Hardware PWM
16
6
Programming
MicroPython, C, C++
C (Arduino IDE)
On-board LED
1
1
Cost
$4
$20
languages
Таблица 1.1: Сравнение Raspberry Pi Pico и Arduino UNO.
1.4 Условия эксплуатации и питание Pico
Рекомендуемые условия эксплуатации Pico:
• рабочая температура: от –20ºC до +85ºC
• напряжение VBUS: +5 В ±10%
• напряжение VSYS: от +1,8 В до +5,5 В
Для генерации напряжения +3,3 В для питания RP2040 используется встроенный импульсный
источник питания (SMPS) из диапазона входных напряжений от 1,8 В до +5,5 В. Например, для
питания Pico можно использовать три щелочные батарейки типа AA, обеспечивающие напряжение
+4,5 В.
● 15
Raspberry Pi Pico for Radio Amateurs
Pico можно питать несколькими способами. Самый простой способ — подключить порт
micro-USB к источнику питания +5 В, например, к USB-порту компьютера или адаптеру
питания +5 В. Это обеспечит питание входа VSYS (см. Рисунок 1.5) через диод Шоттки. Таким
образом, напряжение на входе VSYS равно напряжению VBUS за вычетом падения
напряжения на диоде Шоттки (около +0,7 В). Выводы VBUS и VSYS можно замкнуть, если
плата питается от внешнего USB-порта +5 В. Это немного увеличит входное напряжение и,
следовательно, уменьшит пульсации на VSYS. Напряжение VSYS подается на SMPS через
RT6150, который генерирует фиксированное напряжение +3,3 В для микроконтроллера и
других компонентов платы. VSYS делится на три и доступно на аналоговом входном порту
GPIO29 (ADC3), который можно легко контролировать. GPIO24 проверяет наличие
напряжения VBUS и находится в состоянии ВЫСОКОГО уровня, если VBUS присутствует.
Другой способ питания Pico — подача внешнего напряжения (от +1,8 В до +5,5 В)
непосредственно на вход VSYS (например, от батарей или внешнего источника питания).
Также можно использовать вход USB и входы VSYS одновременно для питания Pico,
например, чтобы обеспечить работу как от батарей, так и от порта USB. В этом случае на
входе VSYS следует установить диод Шоттки, чтобы предотвратить взаимное влияние
источников питания. VSYS будет питаться при более высоком напряжении.
Рис. 1.5: Питание Pico.
1.5 Распиновка микроконтроллера RP2040 и Pico-модуля
На рисунке 1.6 показана распиновка микроконтроллера RP2040, выполненного в 56-выводном
корпусе. Распиновка модуля Pico подробно показана на рис. 1.7. Как видно из рисунка,
большинство выводов выполняют несколько функций. Например, вывод GPIO0 (вывод 1) также
является выводом UART0 TX, выводом I2C0SDA и выводом SPI0 RX.
● 16
Chapter 1 • Raspberry Pi Pico Hardware
Рис. 1.6: Распиновка микроконтроллера RP2040.
Рис. 1.7: Распиновка Pico.
● 17
Raspberry Pi Pico for Radio Amateurs
На рис. 1.8 показана упрощенная блок-схема аппаратного модуля Pico. Обратите внимание,
что контакты GPIO напрямую соединены от микроконтроллера к разъему GPIO. Контакты
GPIO 26, 27, 28 могут использоваться либо как цифровые контакты GPIO, либо как входы
АЦП. На входах АЦП GPIO 26-29 установлены диоды обратной полярности, рассчитанные на
3 В, поэтому входное напряжение не должно превышать 3,3 + 300 мВ. Следует также
отметить, что если RP2040 не питается, подача напряжения на контакты GPIO 26-29 может
привести к утечке через диод в источник питания. С другими контактами GPIO проблем нет, и
напряжение можно безопасно подавать, когда RP2040 не питается.
Рис. 1.8: Упрощенная блок-схема.
1.6 Другие платы на базе микроконтроллера RP2040
Характеристики и внешний вид этих плат в переводе опущен
● 18
Chapter 2 • Raspberry Pi Pico Programming
Глава 2 • Программирование Raspberry Pi Pico
2.1 Обзор
На момент написания этой книги программирование Raspberry Pi Pico осуществлялось с
использованием следующих языков программирования:
• C/C++
• MicroPython
• язык ассемблера
Хотя Pico по умолчанию настроен на работу с мощным и популярным языком
программирования C/C++, многим начинающим проще использовать MicroPython, версию
языка программирования Python, разработанную специально для микроконтроллеров.
В этой главе мы научимся устанавливать и использовать язык программирования
MicroPython. Мы будем использовать текстовый редактор Thonny, разработанный
специально для программ на Python.
В следующих главах будет представлено множество работающих и полностью
протестированных проектов с использованием MicroPython на нашем Pico.
2.2 Установка MicroPython на Pico
Перед использованием MicroPython необходимо установить на Pico. После установки он
остаётся на вашем Pico, если его не заменят чем-либо другим. Для установки MicroPython
требуется подключение к Интернету, хотя и только один раз. Поскольку у Pico нет Wi-Fi, нам
понадобится компьютер с доступом в Интернет. Это можно сделать либо с помощью
Raspberry Pi (например, Raspberry Pi 4), либо с помощью ПК. В этом разделе мы рассмотрим,
как выполнить установку обоими способами.
2.2.1 Использование Raspberry Pi 4 для установки MicroPython на Pico
Последовательность действий следующая:
•
•
•
•
загрузите ваш Raspberry Pi 4 и войдите в систему Desktop
убедитесь, что ваш Raspberry Pi подключен к Интернету
удерживайте кнопку BOOTSEL на вашем Pico
подключите Pico к одному из USB-портов Raspberry Pi 4 с помощью
кабеля micro-USB, удерживая кнопку
• подождите несколько секунд и отпустите кнопку BOOTSEL
• вы должны увидеть Pico в качестве съемного накопителя.
Нажмите OK в окне Removable medium is inserted (рис . 2.1)
● 27
Raspberry Pi Pico for Radio Amateurs
Рис. 2.1: Нажмите ОК.
В окне Manager window вы увидите два файла с именами
INDEX.HTM и INFO_UF2.TXT (см. рис. 2.2).
Рис. 2.2: Вы увидите два файла.
Дважды щелкните файл INDEX.HTM и прокрутите вниз.
• На веб-странице должно отобразиться сообщение Documentation displayed
(рис. 2.3).
● 28
Chapter 2 • Raspberry Pi Pico Programming
Рис. 2.3: Отображаемое сообщение.
Прокрутите вниз и щелкните вкладку MicroPython, а затем нажмите Download UF2,
чтобы загрузить прошивку MicroPython (рис. 2.4). В нижней части экрана должно
появиться сообщение о загруженном файле (рис. 2.5).
Figure 2.4: Download UF2 file.
● 29
Raspberry Pi Pico for Radio Amateurs
Рис. 2.5: Загруженное сообщение.
• Закройте окно браузера, щелкнув значок крестика в правом верхнем углу.
• Откройте файловый менеджер, щелкнув меню, а затем Accessories.
• Откройте папку Downloads (в каталоге /home/pi) и найдите файл с расширением
.uf2. Имя этого файла будет выглядеть примерно так: rp2-pico-20210902-v1.17.uf2
(рис. 2.6).
Рис. 2.6: Найдите файл с расширением .uf2.
• Перетащите этот файл на съемный накопитель Raspberry Pi Pico, обозначенный как
RPI-RP2 (в левом верхнем углу экрана – см. рис. 2.6).
• Через некоторое время прошивка MicroPython будет установлена во внутреннюю
память Pico, и диск исчезнет. Закройте окно.
• На вашем Pico теперь работает MicroPython.
• Выключение Pico не удалит MicroPython из его памяти.
Использование текстового редактора Thonny от Raspberry Pi
Thonny — это бесплатная интегрированная среда разработки (IDE) для Python, разработанная
специально для этой операционной системы. Она включает в себя встроенный текстовый
редактор, отладчик и ряд других полезных утилит, которые могут пригодиться в процессе
разработки программного обеспечения.
● 30
Chapter 2 • Raspberry Pi Pico Programming
В этом разделе мы научимся использовать Thonny, запуская его с Raspberry Pi. Ваш Pico
должен быть подключен к Raspberry Pi. Мы создадим однострочную программу для вывода
сообщения Hello from Raspberry Pi Pico:
Шаги:
На рабочем столе Raspberry Pi щелкните меню, затем Programming, а затем
щелкните Thonny Python IDE (см. рис. 2.7). Автор использовал версию 3.7.3 Thonny,
установленную на его Raspberry Pi 4.
Рис. 2.7: Запустите Thonny на вашем Raspberry Pi.
Щелкните по метке Python в правом нижнем углу окна Thonny (рис. 2.8).
Рис. 2.8: Нажмите Python в правом нижнем углу.
Щелкните, чтобы выбрать MicroPython (Raspberry Pi Pico), как показано на рис. 2.9.
Рис. 2.9: Выберите Raspberry Pi Pico.
● 31
Raspberry Pi Pico for Radio Amateurs
В нижней части экрана, где находится оболочка, должен отображаться номер версии
вашего MicroPython (рис. 2.10).
Рис. 2.10: Отображается номер версии MicroPython.
Теперь мы можем написать нашу простую программу. Введите следующую строку в
нижней части экрана, где отображается Shell. Операторы программы, написанные
вэтой части Thonny, выполняются в режиме реального времени и немедленно. Эта
часть обычно используется для оценки частей программы. Введите:
print("Hello from Raspberry Pi Pico")
и вы должны увидеть сообщение "Hello from Raspberry Pi Pico", как
показано на рис. 2.11.
Рис. 2.11: Отображение сообщения.
Иконки Thonny
В верхней части экрана Thonny вы увидите ряд значков, как показано на рис. 2.12. Функции
этих значков описаны в этом разделе (обратите внимание, что для обозначения значков
используются буквы).
Рис. 2.12: Иконки Тонни.
A: NEW.
B: Open.
C: Save.
D: Run.
E: Debug.
F: Step Over.
G: Step Into.
H: Step Out.
I: Resume.
J: Stop/Restart.
● 32
Этот значок используется для создания нового файла.
Этот значок используется для открытия существующего файла.
Этот значок используется для сохранения файла.
Эта опция используется для запуска текущей программы.
Этот значок используется для отладки текущей программы.
Эта опция используется для пропуска функции в режиме отладки.
Эта опция для пошагового выполнения функции в режиме отладки.
Этот значок используется для выхода из функции в режиме отладки.
Этот значок используется для выхода из функции в режиме отладки.
Эта опция используется для возобновления остановленной сессии.
Chapter 2 • Raspberry Pi Pico Programming
Написание программы с использованием Thonny
В предыдущем разделе мы рассмотрели, как выполнить команду в режиме онлайн с помощью
ThonnyShell. Практически все приложения требуют написания программ. В качестве примера
ниже приведены шаги по написанию и запуску довольно простой однострочной программы для
вывода сообщения «Привет от программы…».
Введите операторы программы в верхней части экрана, как показано на рис. 2.13
Рис. 2.13: Напишите программу в верхней части экрана.
Нажмите File, затем Save As и дайте имя вашей программе, например,
FirstProg. Вы можете сохранить программу либо на Raspberry Pi, либо на Pico.
Нажмите «Raspberry Pi Pico», чтобы сохранить ее на Pico (рис. 2.14). Введите
имя вашей программы (FirstProg) и нажмите «ОК» (обратите внимание, что
файл будет сохранен с расширением .py).
Рис. 2.14: Нажмите Raspberry Pi Pico, чтобы сохранить программу.
Нажмите на зеленую стрелку в верхней части экрана (под кнопкой «Запуск»),
чтобы запустить программу. Результат выполнения программы будет отображен в
нижней части экрана, как показано на рис. 2.15.
Рис. 2.15: Результат выполнения программы.
● 33
Raspberry Pi Pico for Radio Amateurs
2.2.2 Использование ПК (Windows 10) для установки MicroPython на Pico
В разделе 2.2.1 мы научились устанавливать MicroPython на Pico с помощью Raspberry Pi 4. В
этом разделе мы рассмотрим, как установить MicroPython, используя только ПК с операционной
системой Windows 10. Этот вариант следует выбрать, если у вас нет доступа к Raspberry Pi.
Последовательность действий следующая:
• убедитесь, что ваш компьютер подключен к интернету
• удерживайте кнопку BOOTSEL на вашем Pico
• подключите Pico к USB-порту вашего ПК с помощью кабеля micro-USB,
удерживая кнопку
• подождите несколько секунд и отпустите кнопку BOOTSEL
• вы должны увидеть Pico в качестве съемного диска с именем RPI-RP2, как показано
на рис. 2.16 (в данном случае диск E)
Рис. 2.16: Pico в качестве съемного накопителя RPI-RP2.
Щелкните по накопителю RPI-RP2. Вы увидите два файла с именами
INDEX.HTM и INFO_UF2.TXT (см. рис. 2.17).
Рис. 2.17: Вы увидите два файла.
•Дважды щелкните файл INDEX.HTM и прокрутите вниз.
•Вы должны увидеть сообщение «Raspberry Pi Documentation»
на веб-странице (рис. 2.3).
● 34
Chapter 2 • Raspberry Pi Pico Programming
• Прокрутите вниз и щелкните вкладку MicroPython, а затем нажмите Download UF2,
чтобы загрузить прошивку MicroPython (Рис. 2.4). Вы должны увидеть загруженный
файл в папке Downloads (рис. 2.18). Имя этого файла будет примерно таким:
rp2-pico-20210902-v1.17.uf2.
Рис. 2.18: Загруженный файл.
• откройте папку Downloads и найдите файл с расширением .uf2
перетащите этот файл на съемный диск Raspberry Pi Pico с именем: RPI-RP2
• через некоторое время прошивка MicroPython будет установлена во внутреннюю
память Pico, и диск RPI-RP2 исчезнет
• теперь на вашем Pico работает MicroPython
.
• выключение Pico не удалит MicroPython из его памяти
Использование текстового редактора Thonny на ПК
В предыдущем разделе мы научились использовать Thonny на Raspberry Pi и разрабатывать,
сохранять и запускать программы на Pico. В этом разделе мы будем использовать Thonny на
ПК, поэтому для разработки и запуска наших программ не потребуется Raspberry Pi.
Прежде всего, нам нужно установить Thonny на наш ПК (если он еще не установлен).
Шаги следующие:
• перейдите на веб-сайт Thonny.org: https://thonny.org/
• нажмите на ссылку в правом верхнем углу экрана, чтобы установить
Thonny (см. рис. 2.19)
Рис. 2.19: Нажмите, чтобы установить Thonny.
На рабочем столе вашего ПК должен появиться значок (рис. 2.20). Дважды
щелкните по нему, чтобы запустить Thonny.
● 35
Raspberry Pi Pico for Radio Amateurs
Рис. 2.20: Значок Thonny на рабочем столе.
Запуск приложения Thonny на вашем ПК показан на рис. 2.21.
Рис. 2.21: Запуск Thonny на ПК.
• Щелкните по метке Python в правом нижнем углу экрана и выберите
MicroPython (Raspberry Pi Pico).
•
•
•
•
● 36
теперь вы можете писать свои программы
введите следующее выражение в нижней части экрана (в Shell):
print("hello from Thonny on PC")
вы должны увидеть сообщение "hello from Thonny on PC", как показано
на рис. 2.22
Chapter 2 • Raspberry Pi Pico Programming
Рис. 2.22: Отображение сообщения.
В этой книге мы будем использовать Thonny на ПК для написания программ и их
выполнения на Raspberry Pi Pico.
● 37
Raspberry Pi Pico for Radio Amateurs
Глава 3 • Простые программы
3.1 Обзор
В этой главе приведены простые примеры программ, чтобы познакомить читателя с
программированием Raspberry Pi Pico на языке Python. Цель здесь — повторить основные концепции
программирования на Python. Эта книга не ставит целью обучение программированию на Python, и, к
счастью, в Интернете есть множество публикаций и руководств для этой цели.
3.2 Примеры
3.2.1 Среднее арифметическое двух чисел, считанных с клавиатуры
В этом примере с клавиатуры считываются два числа, и отображается их среднее
арифметическое. Цель этого примера — показать, как можно считывать данные с
клавиатуры.
Решение
Программа называется Average, а листинг программы и пример её выполнения показаны на
рис. 3.1. Функция input используется для считывания чисел в виде строк с клавиатуры.
Затем эти строки преобразуются в числа с плавающей запятой и сохраняются в переменных
n1 и n2. Среднее значение вычисляется путем сложения и последующего деления чисел на
два. Результат отображается на экране.
Рис. 3.1: Программа: Averageand sample run.
3.2.2 Среднее значение 10 чисел, считанных с клавиатуры
В этом примере с клавиатуры считываются 10 чисел, и отображается их среднее значение.
Цель этого примера — показать, как можно построить цикл в Python.
● 38
Chapter 3 • Simple Programs – Software Only
Решение
Программа называется Average10, а листинг программы и пример её выполнения показаны
на рис. 3.2. В этой программе построен цикл, который выполняется от 0 до 9 (т.е. 10 раз).
Внутри этого цикла числа считываются с клавиатуры, складываются друг с другом и
сохраняются в переменной sum. Затем вычисляется и отображается среднее значение путем
деления sum на 10. Обратите внимание, что после операторов print не печатается новая
строка, поскольку внутри оператора print используется опция end = ' '.
Рис. 3.2: Программа: Average10and sample run.
3.2.3 Площадь поверхности цилиндра
В этом примере радиус и высота цилиндра считываются с клавиатуры, а его площадь
поверхности отображается на экране.
Решение
Программа называется CylArea, а листинг программы и пример её выполнения показаны на
рис. 3.3. Площадь поверхности цилиндра определяется формулой:
Площадь поверхности = 2 × π × r × h
Где r и d — радиус и высота цилиндра соответственно. В этой программе импортируется
математическая библиотека, чтобы можно было использовать функцию Pic. Площадь поверхности
цилиндра отображается после считывания его радиуса и высоты.
● 39
Raspberry Pi Pico for Radio Amateurs
Рис. 3.3: Программа: CylAreaand и пример выполнения.
3.2.4 Преобразование ºC в ºF
В этом примере программа считывает градусы Цельсия с клавиатуры, преобразует их и
отображает эквивалентные градусы Фаренгейта.
Решение
Программа называется CtoF, а листинг программы и пример ее выполнения показаны
на рис. 3.4. Формула для преобразования
F = 1.8 × C + 32
Рис. 3.4.: Программа: пример запуска CtoFand.
● 40
Chapter 3 • Simple Programs – Software Only
3.2.5 Площадь поверхности и объем цилиндра
В этом примере вычисляются площадь поверхности и объем цилиндра, радиус и
высота которого заданы. Программа использует функцию для вычисления и возврата
площади поверхности и объема.
Решение
Программа называется CylAreaSurf, а листинг программы и пример её выполнения
показаны на рис. 3.5. Площадь поверхности и объём цилиндра задаются
формулами:
Площадь поверхности = 2 × π × r × h
Объём = π × r² × h
Где r и d — радиус и высота цилиндра соответственно. Функция Calc используется для
получения радиуса и высоты цилиндра. Функция возвращает площадь поверхности и объем в
основную программу, которые отображаются на экране.
Рис. 3.5: Программа CylAreaSurf и пример ее выполнения.
3.2.6 Таблица квадратов чисел
В этом примере вычисляются и табулируются квадраты чисел от 1 до 11.
Решение
Программа называется Squares, а листинг программы и пример ее запуска показаны
на рис. 3.6. Обратите внимание, что символ "\t" выводит табуляцию, чтобы данные можно
былоудобно представить в табличном виде.
● 41
Raspberry Pi Pico for Radio Amateurs
Рис. 3.6: Программа: Squaresand, пример выполнения.
3.2.7 Таблица тригонометрических синусов
В этом примере тригонометрический синус представлен в табличном виде
от 0 до 45 градусов с шагом в 5 градусов.
Решение
Программа называется Sines, а листинг программы и пример ее выполнения показаны на
рис. 3.7. Важно отметить, что аргументы тригонометрических функций должны быть в
радианах, а не в градусах.
Рис. 3.7: Программа: пример выходных данных
синусоидального сигнала.
● 42
Chapter 3 • Simple Programs – Software Only
3.2.8 Таблица тригонометрических синуса, косинуса и тангенса
В этом примере тригонометрические значения синуса, косинуса и тангенса представлены в
табличном виде от 0 до 45 градусов с шагом в 5 градусов.
Решение
Программа называется Trig, а листинг программы и пример её выполнения показаны
на рис. 3.8.
Рис. 3.8: Программа: Trig и пример выходных данных.
3.2.9 Тригонометрическая функция требуемого угла
В этом примере угол считывается с клавиатуры. Кроме того, пользователь указывает,
требуется ли sine (s), cosine (c) или tangent (t) угла.
Решение
Программа называется TrigUser, и листинг программы, а также пример ее запуска показаны
на рис. 3.9.
● 43
Raspberry Pi Pico for Radio Amateurs
Рис. 3.9: Программа: TrigUser и пример вывода.
3.2.10 Слова в обратном порядке
Напишите программу, которая считывает слово с клавиатуры, а затем отображает буквы
этого слова в обратном порядке на экране.
Решение
Необходимый фрагмент кода программы показан на рис. 3.10 (программа: Letters).
С клавиатуры считывается слово, которое сохраняется в строковой переменной word.
Затем буквы этого слова отображаются в обратном порядке. Пример выполнения
программы показан на рис. 3.10.
Рис. 3.10: Программа: Letter и пример выходных данных.
● 44
Chapter 3 • Simple Programs – Software Only
3.2.11 Калькулятор
Напишите программу-калькулятор для выполнения четырех простых
математических операций: сложения, вычитания, умножения и деления над двумя
числами, полученными с клавиатуры.
Решение
Необходимый фрагмент кода программы показан на рис. 3.1.1 (программа: Calc). С
клавиатуры принимаются два числа, которые сохраняются в переменных n1 и n2. Затем
принимается требуемая математическая операция, и она выполняется. Результат,
сохраненный в переменной result, отображается на экране. Пользователю предоставляется
возможность завершить программу.
any = 'y'
while any == 'y':
print("\nCalculator Program")
print("==================")
n1 = float(input("Enter first number: "))
n2 = float(input("Enter second number: "))
op = input("Enter operation (+-*/): ")
if op =="+":
result = n1 + n2
elif op == "-":
result = n1 - n2
elif op == "*":
result = n1 * n2
elif op == "/":
result = n1 / n2
print("Result = %f" %(result))
any = input("\nAny more (yn): ")
Рис. 3.11: Программа: Calc.
Пример выполнения программы показан на рис. 3.12.
● 45
Raspberry Pi Pico for Radio Amateurs
Рис. 3.12: Пример выполнения программы.
3.2.12 Игра в кости
Напишите программу для имитации двойного броска кубиков, то есть для отображения двух
случайных чисел от 1 до 6 при каждом запуске.
Решение
Необходимый фрагмент кода программы показан на рис. 3.13 (программа: Dice). Здесь
генератор случайных чисел используется для генерации случайных чисел от 1 до 6 при
нажатии клавиши Enter. Программа завершается при вводе буквы x (или X).
Рис. 3.13: Программа: Dice.
Пример выполнения программы показан на рис. 3.13.
● 46
Chapter 3 • Simple Programs – Software Only
3.2.13 Сортировка списков
Список из 5 стран хранится в виде списка. Напишите программу для сортировки названий этих
стран в алфавитном порядке и последующего их отображения.
Решение
Программа называется Sort, её листинг и пример выполнения показаны
на рис. 3.14.
MyList = ['italy', 'france', 'germany', 'india', 'china']
MyList.sort()
print("Sorted list : ", MyList)
Рис. 3.14: Программа: Sort и пример вывода.
3.2.14 Обработка файлов — запись
В этом примере будет создан текстовый файл с именем MyFile.txt, и в него будет
записан текст «Hello from Raspberry Pi Pico!».
Решение
Программа называется Filew, ее листинг и пример запуска показаны на рис. 3.15.
Файл открывается в режиме записи (w), и текст в него записывается с помощью
функции write. Обратите внимание, что fpi — это дескриптор файла.
Рис. 3.15: Программа:Filew.
3.2.15 Обработка файлов — чтение
В этом примере открывается текстовый файл fileMyFile.txt, созданный в предыдущем
примере, и его содержимое отображается на экране.
Решение
Программа называется Filer, ее листинг и пример выполнения показаны на рис. 3.16. Файл
открывается в режиме чтения (r), и его содержимое отображается.
● 47
Raspberry Pi Pico for Radio Amateurs
Рис. 3.16: Программа:Filer.
3.2.16 Квадраты и кубы чисел
Напишите программу для подсчета квадратов и кубов чисел от 1 до 10.
Решение
Программа называется Cubes, ее листинг и пример запуска показаны на рис. 3.17.
Рис. 3.17: Программа: Cubes и пример вывода.
3.2.17 Таблица умножения
Напишите программу, которая считывает число с клавиатуры и затем отображает расписание
для этого числа от 1 до 12.
Решение
Программа называется Times, ее листинг и пример выполнения показаны на рис. 3.18.
● 48
Chapter 3 • Simple Programs – Software Only
Рис. 3.18: Программа: Times и пример вывода.
3.2.18 Четное или нечетное?
Напишите программу, которая считывает число с клавиатуры, проверяет и отображает,
является ли это число четным или нечетным.
Решение
Программа называется OddEven, ее листинг и пример выполнения показаны на рис. 3.19.
Рис. 3.19: Программа: OddEven и пример вывода.
3.2.19 Двоичные, восьмеричные и шестнадцатеричные числа
Напишите программу для считывания десятичного числа с клавиатуры. Преобразуйте это
число в двоичное, восьмеричное и шестнадцатеричное числа и выведите его на экран.
Решение
Программа называется Conv, ее листинг и пример выполнения показаны на рис. 3.20.
● 49
Raspberry Pi Pico for Radio Amateurs
Рис. 3.20: Программа:Conv и пример вывода.
3.2.20 Сложение двух матриц
Напишите программу для сложения двух заданных матриц и отображения
элементов новой матрицы.
Решение
Программа называется AddMatrix, ее листинг и пример выполнения показаны на рис. 3.21.
Рис. 3.21: Программа: AddMatrix и пример выходных данных.
3.2.21 Фигуры
Напишите программу, использующую функции для вычисления и отображения площадей
фигур: квадрата, прямоугольника, треугольника, круга и цилиндра. Размеры необходимых
сторон должны быть получены с клавиатуры.
● 50
Chapter 3 • Simple Programs – Software Only
Решение
Площади фигур, которые будут использоваться в программе, следующие:
Square: side = a
Rectangle: sides a, b
Circle: radius r
Triangle: base b, height h
Cylinder: radius r, height h
area
area
area
area
area
=
=
=
=
=
a2
ab
πr2
bh/2
2πrh
Необходимый фрагмент кода программы показан на рис. 3.22 (программа:areas.py). Для
каждой фигуры используется своя функция, а размеры сторон принимаются внутри функций.
Основная программа отображает вычисленную площадь для выбранной фигуры.
#---------------------------------------------#
ПЛОЩАДИ ФИГУР
#
===============
#
# Эта программа вычисляет и отображает площади
# различных геометрических фигур
# в списке
#
# Author: Dogan Ibrahim
# File
: areas.py
# Date
: August, 2021
#---------------------------------------------import math
def Square(a):
# квадрат
return a * a
def Rectangle(a, b):
# прямоугольник
return(a * b)
def Triangle(b, h):
# треугольник
return(b * h / 2)
def Circle(r):
# круг
return(math.pi * r * r)
def Cylinder(r, h):
# цилиндр
return(2 * math.pi * r * h)
print("AREAS OF SHAPES")
print("===============\n")
print("What is the shape?: ")
● 51
Raspberry Pi Pico for Radio Amateurs
shape = input("Square (s)\nRectangle(r)\nCircle(c)\n\
Triangle(t)\nCylinder(y): ")
shape = shape.lower()
if shape == 's':
a = float(input("Enter a side of the square: "))
area = Square(a)
s = "Square"
elif shape == 'r':
a = float(input("Enter one side of the rectangle: "))
b = float(input("Enter other side of the rectangle: "))
area = Rectangle(a, b)
s = "Rectangle"
elif shape == 'c':
radius = float(input("Enter radius of the circle: "))
area = Circle(radius)
s = "Circle"
elif shape == 't':
base = float(input("Enter base of the triangle: "))
height = float(input("Enter height of the triangle: "))
area = Triangle(base, height)
s = "Triangle"
elif shape == 'y':
radius = float(input("Enter radius of cylinder: "))
height = float(input("Enter height of cylinder: "))
area = Cylinder(radius, height)
s = "Cylinder"
print("Area of %s is %f" %(s, area))
Рис. 3.22: Листинг программы.
Пример выполнения программы показан на рис. 3.23.
Рис. 3.23: Пример выполнения программы.
● 52
Chapter 4 • Amateur Radio Programs — Software Only
Глава 4 • Программы для радиолюбителей
4.1 Обзор
В этой главе приведены простые примеры программ, основанные на принципах электронной
инженерии, чтобы познакомить читателя с программированием Raspberry Pi Pico с
использованием языка Python. Цель здесь — разработка программ, полезных для
радиолюбителей. Приведенные в этой главе программы не используют никакого внешнего
оборудования.
4.2 Примеры
4.2.1 Идентификатор цветовой кодировки 4-полосного резистора
В этом проекте пользователь вводит три цвета 4-полосного резистора, и программа
вычисляет и отображает значение резистора в омах. Допуск резистора не отображается.
Цель этого примера — показать, как можно использовать ввод с клавиатуры, списки и
управляющие операторы в программе.
4.2.1 Идентификатор цветовой кодировки 4-полосного резистора
Чёрный:
Коричневый:
Красный:
Оранжевый:
Желтый:
Зеленый:
Синий:
Фиолетовый:
Серый:
Белый:
0
1
2
3
4
5
6
7
8
9
Первые два цвета определяют первые две цифры значения, а последний цвет определяет
множитель. Например, красный - красный - оранжевый соответствует 2–2–3, т.е. 22 × 10³ = 22
000 Ом (рис. 1).
Рис. 4.1: Резистор 22 000 Ом.
На рис. 4.2 показан листинг программы (программа: resistor.py). В начале программы
создается список с именем colour, в котором хранятся допустимые цвета резисторов. Затем
отображается заголовок, и создается цикл while, который выполняется до тех пор, пока
строковая переменная yn равна y. Внутри цикла программа считывает три цвета с клавиатуры,
используя функции input, и сохраняет их в виде строк в переменных FirstColour,
SecondColour и ThirdColour. Затем эти строки преобразуются в нижний регистр, чтобы они
соответствовали значениям, указанным в списке. Индексы этих цветов в списке затем
находятся с помощью вызовов функций вида colours.index.
●
53
Raspberry Pi Pico for Radio Amateurs
Например, если пользователь ввел red, то соответствующее значение индекса будет равно 2.
Затем значение резистора вычисляется путем умножения первого числа цвета на 10 и
добавления ко второму числу цвета. Затем результат умножается на степень 10 третьего
цветового диапазона. Окончательный результат отображается на экране. Затем программа
спрашивает пользователя, хочет ли он продолжить. Если ответ y, программа возвращается к
началу, в противном случае программа завершается.
#=================================================
#
ЦВЕТОВАЯ КОДИРОВКА РЕЗИСТОРОВ
#
---------------------------------
#
# Пользователь вводит три цвета резистора,
# и программа вычисляет и отображает значение
# резистора в Омах
#
# Program: resistor.py
# Date
: August, 2021
# Author : Dogan Ibrahim
#===================================================
colours = ['black','brown','red','orange','yellow','green',\
'blue','violet','grey','white']
print("RESISTOR VALUE CALCULATOR")
print("=========================")
yn = "y"
while yn == 'y':
FirstColour = input("Enter First Colour: ")
SecondColour = input("Enter Second Colour: ")
ThirdColour = input("Enter Third Colour: ")
#
# Преобразование в нижний регистр
#
FirstColour = FirstColour.lower()
SecondColour = SecondColour.lower()
ThirdColour = ThirdColour.lower()
#
# Нахождение значений цветов
#
FirstValue = colours.index(FirstColour)
SecondValue = colours.index(SecondColour)
ThirdValue = colours.index(ThirdColour)
#
# Теперь вычислим значение резистор
#
Resistor = 10 * FirstValue
● 54
+ SecondValue
Chapter 4 • Amateur Radio Programs — Software Only
Resistor = Resistor * (10 ** ThirdValue)
print("Resistance = %d Ohms" % (Resistor))
#
# Запросите больше
#
yn = input("\nDo you want to continue?: ")
yn = yn.lower()
Рис. 4.2: Листинг программы.
На рис. 4.3 показан типичный запуск программы.
Рис. 4.3: Типичный запуск программы.
4.2.2 4-полосный цветовой идентификатор резисторов
Программа, представленная на рис. 4.2, может вычислять значения резисторов, если они
больше или равны 10 Ом. Для резисторов меньшего сопротивления в качестве третьего
цвета используются золотой и серебряный цвета. Золотой цвет делит результат на 10, а
серебряный — на 100. Например, красный-красный-серебряный соответствует 0,22 Ом
(рис. 4.4). Эта программа вычисляет значения всех типов резисторов, обозначенных 4
цветовыми полосами.
Рис. 4.4: Резистор 0,22 Ом.
На рис. 4.5 показан листинг программы (program:resistor2.py). В список добавлены золотой и
серебряный цвета. Индексы золотого и серебряного цветов в списке равны 10 и 11
соответственно. Большая часть программы аналогична рис. 4.2, за исключением того, что если
третий цвет — золотой, то результат делится на 10. Аналогично, если третий цвет —
серебряный, то результат делится на 100. Обратите внимание, что если значение резистора
меньше 10 Ом, то оно отображается в формате с плавающей запятой с двумя знаками после
запятой с помощью параметра форматирования вывода %3.2f.
● 55
Raspberry Pi Pico for Radio Amateurs
#=================================================
#
ЦВЕТОВАЯ КОДИРОВКА РЕЗИСТОРОВ
#
---------------------------------
#
# Пользователь вводит три цвета резистора, и программа
# вычисляет и отображает значение резистора в Омах.
# Программа определяет все типы резисторов
# с помощью 4 цветовых полос.
#
# Program: resistor2.py
# Date
: August, 2021
# Author : Dogan Ibrahim
#===================================================
colours = ['black','brown','red','orange','yellow','green',\
'blue','violet','grey','white', 'gold', 'silver']
print("RESISTOR VALUE CALCULATOR")
print("=========================")
yn = "y"
while yn == 'y':
FirstColour = input("Enter First Colour: ")
SecondColour = input("Enter Second Colour: ")
ThirdColour = input("Enter Third Colour: ")
#
# Преобразование в нижний регистр
#
FirstColour = FirstColour.lower()
SecondColour = SecondColour.lower()
ThirdColour = ThirdColour.lower()
#
# Нахождение значений цветов
#
FirstValue = colours.index(FirstColour)
SecondValue = colours.index(SecondColour)
ThirdValue = colours.index(ThirdColour)
#
# Теперь вычислим значение резистора
#
Resistor = 10 * FirstValue
+ SecondValue
if ThirdValue == 10:
Resistor = Resistor / 10.0
print("Resistance = %3.2f Ohms" % (Resistor))
elif ThirdValue == 11:
Resistor = Resistor/100.0
print("Resistance = %3.2f Ohms" % (Resistor))
● 56
Chapter 4 • Amateur Radio Programs — Software Only
else:
Resistor = Resistor * (10 ** ThirdValue)
print("Resistance = %d Ohms" % (Resistor))
#
# Запросите больше
#
yn = input("\nDo you want to continue?: ")
yn = yn.lower()
Рис. 4.5: Листинг программы.
На рис. 4.6 показан типичный запуск программы.
Рис. 4.6: Типичный запуск программы.
4.2.3 Резистивный делитель напряжения
В этом примере программы мы вычисляем сопротивления в резистивном делителе
напряжения. Цель этого примера — показать, как использовать ввод с клавиатуры и
операторы управления потоком в программе.
Резистивные делители напряжения состоят из двух резисторов. Эти схемы используются для
понижения напряжения до желаемого значения. На рис. 4.7 показана типичная схема резистивного
делителя напряжения. Здесь Vin и Vo — входное и выходное напряжения соответственно. R1 и R2 —
пары резисторов, используемые для понижения напряжения от Vin до Vo. Для получения желаемого
выходного напряжения можно использовать большое количество пар резисторов. Выбор больших
резисторов приводит к малому току в цепи, а выбор малых резисторов — к большему току. В данной
схеме пользователь задает Vin, Vo и R2. Программа вычисляет необходимое значение R1 для
понижения напряжения до желаемого уровня. Кроме того, программа отображает выходное
напряжение с выбранными физическими резисторами.
Рис. 4.7: Резистивный делитель напряжения.
● 57
Raspberry Pi Pico for Radio Amateurs
Выходное напряжение определяется формулой:
Vo = Vin R2 / (R1 + R2)
R1 определяется формулой:
R1 = (Vin – Vo) R2 / Vo
Приведенная выше формула используется для вычисления требуемого значения R1,
если известны Vin, Vo и R2.
На рис. 4.8 показан листинг программы (program:divider.py). В начале программы
отображается заголовок. Затем программа считывает с клавиатуры значения Vin, Vo и R2.
Программа вычисляет R1 и отображает R1 и R2. Затем пользователю предлагается ввести
выбранное физическое значение для R1. После ввода выбранного значения R1 программа
отображает Vin, Vo, R1 и R2 и спрашивает пользователя, является ли результат приемлемым.
Если ответ на этот вопрос «y», программа завершается. Если же ответ «n», пользователю
предоставляется возможность повторить попытку.
#======================================================
#
ДЕЛИТЕЛЬ НАПРЯЖЕНИЯ
#
----------------------
#
# Это программа для схемы резистивного делителя напряжения.
# Программа вычисляет значения сопротивления, которые
# понизят входное напряжение до желаемого значения.
#
# Program: divider.py
# Date
: August, 2021
# Author : Dogan Ibrahim
#=======================================================
print("RESISTIVE POTENTIAL DIVIDER")
print("===========================")
R1flag = 1
R2flag = 0
while R1flag == 1:
Vin = float(input("\nInput voltage (Volts): "))
Vo = float(input("Desired output voltage (Volts): "))
R2 = float(input("Enter R2 (in Ohms): "))
#
# Вычислить R1
#
R1 = R2 * (Vin - Vo) / Vo
print("\nR1 = %3.2f Ohms R2 = %3.2f Ohms" %(R1, R2))
#
# Считать выбранное физическое R1 и отобразить фактическое Vo
● 58
Chapter 4 • Amateur Radio Programs — Software Only
#
NewR1 = float(input("\nEnter chosen R1 (Ohms): "))
#
# Отобразить и распечатать выходное напряжение с выбранным резистором R1.
#
print("\nWith the chosen R1,the results are:")
Vo = R2 * Vin / (NewR1 + R2)
print("R1 = %3.2F R2 = %3.2f Vin = %3.2f Vo = %3.3f" %(NewR1,R2,Vin,Vo))
#
# Проверьте, устраивают ли вас эти значения?
#
happy = input("\nAre you happy with the values? ")
happy = happy.lower()
if happy == 'y':
break
else:
mode = input("Do you want to try again? ")
mode = mode.lower()
if mode == 'y':
R1flag = 1
else:
R1flag = 0
break
Рис. 4.8: Листинг программы.
Рис. 4.9 показывает типичный запуск программы.
Рис. 4.9: Типичный запуск программы.
4.2.4 Резистивный аттенюатор — равные сопротивления источника и нагрузки
В этом примере мы рассчитываем сопротивления в цепи резистивного аттенюатора, где
сопротивления источника и нагрузки равны. Цель этого примера — показать, как использовать
ввод с клавиатуры, операторы управления потоком и логарифмы в программе.
● 59
Raspberry Pi Pico for Radio Amateurs
Резистивный аттенюатор — это двухполюсная резистивная цепь, предназначенная для
ослабления мощности, подаваемой на его входные клеммы. Аттенюаторы обычно
используются в радио-, аудио- и коммуникационных схемах для ослабления более сильного
сигнала, а также для обеспечения согласования импедансов между источником и нагрузкой.
Эффективность аттенюатора выражается в количестве децибел (дБ), на которое уменьшился
входной сигнал. Математически это выражается как логарифм по основанию 10 отношения
выходного сигнала к входному сигналу, умноженный на 20, и называется децибелом:
dB = 20 log10 Vo / Vin (4.1)
Например, если отношение выходного/входного напряжения равно 0,707, это соответствует –3
дБ. Аналогично, отношение 0,5 соответствует –6 дБ. Чтобы найти фактическое отношение
напряжений при заданном значении дБ, необходимо взять антилогарифм, как показано в
следующей формуле:
Vo / Vin = antilog10 (dB / 20) (4.2)
Например, –10 дБ соответствует коэффициенту напряжения
Vo / Vin = antilog10 (–0.5) = 0.316
Существует множество типов резистивных аттенюаторов, но наиболее распространены схемы
Т-образного и П-образного типов, каждая из которых содержит 3 резистора. На рис. 4.10
показан аттенюатор Т-образного типа с двумя одинаковыми резисторами R1 и R2.
Рис. 4.10: Резистивный Т-образный аттенюатор.
Расчетные уравнения для этой схемы приведены ниже (подробнее см. на веб-сайте):
https://www.electronics-tutorials.ws/attenuators/pi-pad-attenuator.html
В данной схеме предполагается, что сопротивление источника и нагрузки равны:
(4.3)
(4.4)
● 60
Chapter 4 • Amateur Radio Programs — Software Only
Где Z — сопротивление источника, равное сопротивлению нагрузки, а K — коэффициент
затухания, где:
K = antilog10(dB / 20) = 10dB/20
Например, для затухания 6 дБ, K будет равно 106/20 = 1,9953. В качестве альтернативы, если
мы хотим ослабить входной сигнал в 12 раз, то значение K будет равно 12.
На рис. 4.11 снова показан резистивный аттенюатор П-образного типа с двумя одинаковыми
резисторами R1 и одним резистором R2.
Рис. 4.11: Резистивный аттенюатор П-типа.
Уравнения схемы приведены ниже (подробнее см. на веб-сайте) :
https://www.electronics-tutorials.ws/attenuators/pi-pad-attenuator.html
В данной схеме предполагается, что сопротивление источника и нагрузки равны:
(4.5)
(4.6)
Где Z — сопротивление источника, равное сопротивлению нагрузки,
а K — коэффициент импеданса, как и ранее.
На рис. 4.12 показан листинг программы (program:attenuator.py). После отображения
заголовка пользователю предлагается ввести сопротивление источника (которое также
является нагрузкой) Z, коэффициент затухания K в децибелах и тип используемой схемы — T
или P (для "Pi"). Программа вычисляет и отображает значения резисторов.
● 61
Raspberry Pi Pico for Radio Amateurs
#---------------------------------------------------#
КОНСТРУКЦИЯ РЕЗИСТИВНОГО АТТЕНЮАТОРА
#
=========================================
#
# Эта программа проектирует резистивный аттенюатор Т-образного или
# П-образного типа. Пользователь вводит сопротивление источника
# (а также нагрузки), коэффициент ослабления и тип конструкции.
#
# Author: Dogan Ibrahim
# File
: attenuator.py
# Date
: August, 2021
#---------------------------------------------------print("Resistive Attenuator Design")
print("===========================")
Z = float(input("Enter source resistance in Ohms: "))
Kdb = float(input("Enter attenuation Factor in dB: "))
T = input("Enter attenuator type (T or P): ")
T = T.lower()
K = pow(10.0, Kdb/20.0)
if T == 't':
R1 = Z * (K - 1) / (K + 1)
R2 = R1
R3 = 2 * Z * K / (K * K - 1)
elif T == 'p':
R1 = Z * (K + 1) / (K - 1)
R3 = R1
R2 = Z * (K * K - 1) / (2 * K)
print("\nResults:")
print("-------")
print("Z = %f Ohms\nK = %f dB\nK (Vi/Vo) = %f\nR1=%f Ohms\nR2=%f Ohms\
\nR3=%f Ohms"
%(Z, Kdb, K, R1, R2, R3))
Рис. 4.12: Листинг программы.
Пример выполнения программы показан на рис. 4.13. Параметры проектирования следующие:
Сопротивление источника (нагрузки), Z = 50 Ом, коэффициент затухания = 12 децибел,
тип затухания = T
Разработанная схема показана на рис. 4.14.
● 62
Chapter 4 • Amateur Radio Programs — Software Only
Рис. 4.13: Пример выполнения программы.
Рис. 4.14: Схема аттенюатора.
4.2.5 Резистивный аттенюатор — неравные сопротивления источника и нагрузки
В этом примере мы рассчитываем сопротивления в цепи резистивного аттенюатора, где
сопротивления источника и нагрузки могут быть неравными. Цель этого примера — показать, как
использовать ввод с клавиатуры, операторы управления потоком и логарифмы в программе.
В аттенюаторе, где сопротивления источника и нагрузки неравны, для расчета значений
сопротивлений используются разные формулы. В этом разделе мы рассмотрим только
П-образную схему, показанную на рис. 4.15.
Рис. 4.15: Аттенюатор П-образного типа с различными сопротивлениями
источника и нагрузки.
Уравнения расчета показаны на рис. 4.16.
● 63
Raspberry Pi Pico for Radio Amateurs
Рис. 4.16: Уравнения для расчета аттенюатора Pi.
На рис. 4.1.7 показан листинг программы (program:attenuator2.py). После отображения
информации пользователю предлагается ввести сопротивление источника и нагрузки ZS и ZL,
а также коэффициент затухания K в децибелах. Программа вычисляет и отображает значения
резисторов.
#---------------------------------------------------#
ПРОЕКТИРОВАНИЕ
#
=======================================
АТТЕНЮАТОРА ТИПА Pi
#
# Эта программа проектирует резистивный аттенюатор типа Pi,
# типа Pi, где сопротивление источника
# и нагрузки могут быть
разными
#
# Author: Dogan Ibrahim
# File
: attenuator2.py
# Date
: August, 2021
#---------------------------------------------------import math
print("Resistive Attenuator Design With Different Source & Load")
print("========================================================")
ZS = float(input("Enter source resistance in Ohms: "))
ZL = float(input("Enter load resistance in Ohms: "))
Kdb = float(input("Enter attenuation Factor in dB: "))
K = pow(10.0, Kdb/20.0)
R1 = ZS * ((K * K - 1) / (K * K - 2 * K * math.sqrt(ZS / ZL) + 1))
● 64
Chapter 4 • Amateur Radio Programs — Software Only
R2 = 0.5 * (math.sqrt(ZS * ZL)) * (K * K - 1) / K
R3 = ZL * ((K * K - 1) / ( 1 + K * K - (2 * K / math.sqrt(ZS/ZL))))
print("\nResults:")
print("-------")
print("ZS = %f Ohms\nZL = %f Ohms\nK = %f dB\nK (Vi/Vo) = %f\nR1=%f Ohms\nR2=%f
Ohms\nR3=%f Ohms"%(ZS, ZL, Kdb, K, R1, R2, R3))
Рис. 4.17: Листинг программы.
Пример выполнения программы показан на рис. 4.18. Параметры проектирования
следующие:
Сопротивление источника, ZS = 75 Ом;
Сопротивление нагрузки, ZL = 50 Ом;
Коэффициент затухания = 6 децибел.
Рис. 4.18: Пример выполнения программы.
Разработанная схема показана на рис. 4.19.
Рис. 4.19: Схема аттенюатора.
4.2.6 Стабилизатор напряжения на основе стабилитрона
Во многих случаях радиолюбителям требуются недорогие и простые стабилизаторы постоянного
напряжения. В этом примере мы представим программу, которая поможет разработать схему
стабилизатора напряжения на основе стабилитрона.
● 65
Raspberry Pi Pico for Radio Amateurs
Стабилитроны (рисунок 4.20) применяются в схемах стабилизаторов напряжения.
Стабилитрон похож на диод общего назначения. Когда диод смещен в прямом
направлении, он ведет себя так же, как обычный сигнальный диод, но при смещении в
обратном направлении напряжение остается постоянным в широком диапазоне токов.
Благодаря этой характеристике стабилитроны используются в качестве источников
фиксированного напряжения в источниках питания.
Figure 4.20: Стабилитрон
Типичное прямое напряжение диода при токе 1 мА составляет около 0,6 В. Как показано на
рис. 4.21, в обратном направлении течет небольшой ток утечки. По мере приближения к
напряжению пробоя ток начинает лавинообразным и напряжение на стабилитроне
становится почти постоянным. Существует минимальный ток, который переводит
стабилитрон в зону пробоя, и максимальный ток, при котором он может быть повреждено,
если ток увеличится.
Рис. 4.21: Типичные характеристики стабилитрона
Стабилитроны доступны с номиналами от 2,4 В до 200 В, а некоторые популярные
из них рассчитаны на 2,7 В, 3,3 В, 4,7 В, 5,1 В, 10 В, 12 В, 15 В и т. д.
● 66
Chapter 4 • Amateur Radio Programs — Software Only
На рис. 4.22 показан стабилитрон, используемый в качестве стабилизатора
напряжения. Входное напряжение подается на катод диода через резистор. Схема
стабилизатора напряжения зависит от правильного выбора резистора.
Рис. 4.22: Схема стабилизатора напряжения
Расчет резистора Rs зависит от требований к току нагрузки, а его минимальное
значение определяется по формуле:
Rs = (Vin – Vz) / (Izmin + ILmax) (4.7)
Где Vin — входное напряжение, Vz — напряжение стабилитрона, Izmin —
минимальный ток стабилитрона (или испытательный ток стабилитрона в
технических характеристиках), а ILmax — максимальный ток нагрузки. Прежде чем
выбирать стабилитрон для применения, мы должны убедиться, что максимальная
номинальная мощность диода не превышается при отсутствии нагрузки. Это дается:
Pz = Vz × Is (4.8)
Где Is = (Vin – Vz) / Rs
(4.9)
Мощность резистора рассчитывается следующим образом:
PRs = (Vin – Vz) × Is (4.10)
На рис. 4.23 показан листинг программы (программа: zener.py). В начале программы
отображается заголовок, и пользователю предлагается ввести Vin, Vz, Izmin и ILmax.
Требуемое значение резистора, минимальные номинальные мощности резистора и
стабилитрона рассчитываются и отображаются.
#---------------------------------------------------#
СТАБИЛИЗАТОР НАПРЯЖЕНИЯ НА ОСНОВЕ СТАБИЛИТРОНА
#
===================================================
#
# Это программа для проектирования стабилизатора напряжения на основе
,
# стабилитрона, которая вычисляет требуемое значение сопротивления
#
# Author: Dogan Ibrahim
# File
: zener.py
# Date
: August, 2021
● 67
Raspberry Pi Pico for Radio Amateurs
#---------------------------------------------------print("Zener Diode Voltage Regulator")
print("=============================")
Vin = float(input("Enter Vin (Volts): "))
Vz = float(input("Enter zener (load) voltage (Volts): "))
Izmin = float(input("Enter minimum zener current (mA): "))
IzminA = Izmin / 1000.0
ILmax = float(input("Enter maximum load current (mA): "))
ILmaxA = ILmax / 1000.0
#
# Теперь произведите расчеты.
#
Rs = (Vin - Vz) / (IzminA + ILmaxA)
Is = (Vin - Vz) / Rs
Pz = Vz * Is
Pz = Pz * 1000.0
Prs = (Vin - Vz) * Is
Prs = Prs * 1000.0
#
# Отобразить результаты
#
print("\nResults")
print("=======")
print("Vin=%3.2fV\nVz=%3.2fV\nIzmin=%3.2fmA\nILmax=%3.2fmA\nRs=%3.2f Ohms\
\nPrs=%3.2fmW\nPz=%3.2fmW" %(Vin, Vz, Izmin, ILmax, Rs, Prs, Pz))
Рис. 4.23: Листинг программы.
Пример выполнения программы показан на рис. 4.24, которая имеет следующие характеристики:
Vin = 10 V
Vz = 5.1 V
Izmin = 5 mA
ILmax = 100 mA
● 68
Chapter 4 • Amateur Radio Programs — Software Only
Рис. 4.24: Пример выполнения программы.
На рис. 4.25 показана разработанная схема стабилитрона, выходное напряжение которой
составляет 5,1 В. Требуемое значение сопротивления рассчитано как 46,67 Ом. Следует выбрать
47 Ом, что соответствует 1 Вт, в качестве ближайшего физического значения сопротивления.
Стабилитрон на 5,1 В должен иметь номинальную мощность приблизительно 1 Вт.
Рис. 4.25: Схема на стабилитроне.
4.2.7 Частотная характеристика RC-цепи
RC-цепи широко используются в любительской радиосвязи в качестве простых пассивных
фильтров. В этом примере мы рассчитаем частотную характеристику (амплитуду и фазу)
RC-цепи и представим результаты в табличном виде на экране.
Частотная характеристика цепи представляет собой изменение её амплитуды и фазового
угла при изменении частоты. В данном примере мы рассмотрим простую RC-цепь,
показанную на рис. 4.26, со значениями компонентов R = 470 Ом и C = 20 микрофарад, где
конденсатор является выходным. Амплитуда (передаточная функция) и фаза частотной
характеристики этой цепи определяются следующей формулой:
(4.11)
Величина обычно обозначается в децибелах:
(4.12)
● 69
Raspberry Pi Pico for Radio Amateurs
А вот эта фаза:
(4.13)
Где W = 2πf, а f — частота.
В данном исследовании мы рассчитаем амплитуду в децибелах и фазу в градусах при
изменении частоты от 0 до 150 Гц с шагом 10 Гц.
Рис. 4.26: RC-цепь, использованная в рассматриваемом примере.
На рис. 4.27 показан листинг программы (program:freqrc.py). В начале программы значения R
и C считываются с клавиатуры. Затем программа вычисляет амплитуду в децибелах и
фазовый угол в градусах при изменении частоты и сохраняет результаты в файл.
#===================================================
#
Частотная характеристика RC-цепи
#
================================
#
# Эта программа вычисляет частотную характеристику
# RC-цепи и выводит результаты в таблицу
#
# Author: Dogan Ibrahim
# File:
freqrc.py
# Date:
August, 2021
#===================================================
import math
print("RC Frequency Response")
print("=====================")
#
# Прочитайте значения компонентов.
#
R = float(input("Enter R in Ohms: "))
C = float(input("Enter C in microfarads: "))
C = C / 1000000.0
print("Frequency (Hz)
● 70
Magnitude (dB)
Phase (degrees)\n")
Chapter 4 • Amateur Radio Programs — Software Only
for freq in range(0, 160, 10):
w = 2.0 * freq * math.pi
d = w * C * R
denom = d * d + 1
M = math.sqrt(1 / denom)
M = 20 * math.log10(M)
phase = -math.degrees(math.atan(d))
print("%3d
%10.4f
%10.4f" %(freq, M, phase))
Рис. 4.27: Листинг программы.
Рис. 4.28 показывает частотную характеристику на экране.
Рис. 4.28: Вывод программы.
4.2.8 Резонанс в последовательных RLC-цепях
В этом примере мы считываем сопротивление, индуктивность и емкость в последовательно
соединенной RLC-цепи, а затем вычисляем и отображаем резонансную частоту, ток в цепи на
резонансе, напряжение на индукторе и конденсаторе на резонансе, добротность (Q-фактор),
полосу пропускания цепи, а также верхнюю и нижнюю точки –3 дБ на резонансе.
В последовательно-резонансной RLC-цепи существует частотная точка, где емкостное
сопротивление конденсатора становится равным индуктивному сопротивлению индуктора.
Точка, в которой это происходит, называется резонансной частотой цепи.
Последовательно-резонансные цепи используются в качестве резонансных контуров в
системах связи, сетевых фильтрах, фильтрах шума и т. д. Резонансная частота RLC-цепи
определяется следующей формулой:
(4.14)
● 71
Raspberry Pi Pico for Radio Amateurs
Ток в цепи в резонансе определяется следующим образом:
(4.15)
Индуктивное сопротивление в резонансе определяется следующим образом:
(4.16)
Напряжение на индукторе и конденсаторе в резонансе определяется следующими формулами:
(4.17)
Добротность (Q-фактор) резонансного контура определяется формулой:
(4.18)
Пропускная способность определяется следующим образом:
(4.19)
Верхняя и нижняя границы частотного диапазона –3 дБ определяются следующим образом:
(4.20)
и
(4.21)
На рис. 4.29 показано определение полосы пропускания в резонансном контуре.
● 72
Chapter 4 • Amateur Radio Programs — Software Only
Рис. 4.29: Ширина полосы пропускания в резонансном контуре.
На рис. 4.30 показан листинг программы (program:resonance.py). Программа считывает
значения сопротивления, индуктивности, емкости и приложенного напряжения и вычисляет
различные параметры цепи в резонансе. Вычисленные значения отображаются на экране.
#==============================================================
#
Расчеты резонанса последовательного RLC-цепи
#
=========================================
#
# Эта программа считывает значения RLC,
# вычисляет и отображает все значения, связанные с резонансом.
#
# Author: Dogan Ibrahim
# File
: resonance.py
# Date
: August 2021
#==============================================================
import math
#
# Прочитайте составные части схемы.
R = float(input("Enter R: "))
L = float(input("Enter L: "))
C = float(input("Enter C: "))
V = float(input("Enter V: "))
L = L /1000.0
#перевести в генри
C = C / 1000000.0
# перевести в фарад
#
# Теперь выполните вычисления.
#
● 73
Raspberry Pi Pico for Radio Amateurs
LC = math.sqrt(L * C)
fr = 1.0 / (2*math.pi*LC)
#резонансная частота
Ir = V / R
# ток в цепи
Xl = 2 * math.pi * fr * L
# индуктивное сопротивление
Vl = Ir * Xl
# напряжение на L и C
Q = 2 * math.pi * fr * L / R
# Q фактор
BW = fr / Q
# полоса пропускания
fl = fr - BW / 2
# нижняя частота -3 дБ
fh = fr + BW / 2
# верхняя частота -3 дБ
print("fr(Hz)
= %10.2f" %(fr))
print("I(A)
= %10.2f" %(Ir))
print("X1 (Ohms)
= %10.2f" %(Xl))
print("V1 (Volts) = %10.2f" %(Vl))
print("Q
= %10.2f" %(Q))
print("BW
= %10.2f" %(BW))
print("fl (Hz)
= %10.2f" %(fl))
print("fh (Hz)
= %10.2f" %(fh))
Рис. 4.30: Листинг программы.
На рис. 4.31 показан типичный запуск программы. Обратите внимание, что
сопротивление указано в омах, емкость — в микрофарадах, индуктивность — в
миллигенри, а напряжение — в вольтах. Частота отображается в герцах.
Рис. 4.31: Типичный запуск программы.
4.2.9 Расчет индуктивности однослойной катушки
Однослойные катушки используются практически во всех устройствах связи. В этом примере
мы рассчитаем индуктивность однослойной катушки с воздушным сердечником, зная её
диаметр, длину и количество витков.
Индуктивность однослойной катушки с воздушным сердечником можно рассчитать с помощью
формулы Уилера. Приведённая ниже формула точна с погрешностью до 1% для L/D > 0,4, то
есть катушка не слишком короткая. Для коротких катушек эта формула не очень подходит:
● 74
Chapter 4 • Amateur Radio Programs — Software Only
(4.22)
Где L — индуктивность в микрогенри, N — количество витков, D — диаметр катушки в см, а L
— длина катушки в см.
На рис. 4.32 показан листинг программы (program:coil.py). Программа считывает значения D,
N и L с клавиатуры. Затем вычисляется и отображается индуктивность. Пользователя
предупреждают, что результаты могут быть неточными, если катушка не закорочена.
На рис. 4.33 показан типичный запуск программы.
#=====================================================================
#
Индуктивность однослойной катушки
#
==============================
#
# Эта программа вычисляет индуктивность однослойной катушки с воздушным
# сердечником. Количество витков, диаметр и длина считываются с клавиатуры.
#
# Author: Dogan Ibrahim
# File
: coil.py
# Date
: August 2021
#=====================================================================
N = float(input("Enter Number of turns: "))
D = float(input("Enter Diameter (cm): "))
L = float(input("Enter Length (cm): "))
#
# Теперь выполните расчет и отобразите индуктивность
#
Ind = (D * D * N * N) / (45 * D + 100* L)
print("Inductance = %10.4f" %(Ind))
if L / D <= 0.4:
print("Coil is too short, may not be accurate")
else:
print("Inductance (microhenries)= %10.4f" %(Ind))
Рис. 4.32: Листинг программы.
Рис. 4.33: Типичный запуск программы.
● 75
Raspberry Pi Pico for Radio Amateurs
4.2.10 Расчёт однослойной катушки для требуемой индуктивности
В этом примере мы определим диаметр катушки D, длину катушки Len и требуемую
индуктивность, а затем рассчитаем необходимое количество витков N. Также отображается
диаметр требуемой проволоки, предполагая, что катушка намотана плотно, так что
проволоки соприкасаются друг с другом.
Из уравнения (4.22) мы можем записать:
(4.23)
Требуемый диаметр провода определяется формулой Len/N.
На рис. 4.34 показан листинг программы (program:coil2.py). Программа считывает D, Len и L, а
затем вычисляет и отображает N и диаметр проволоки. Пример выполнения программы
приведен на рис. 4.35.
#=====================================================================
#
Индуктивность однослойной катушки
#
==============================
#
# Эта программа рассчитывает необходимое количество витков однослойной катушки
# с воздушным сердечником. Также рассчитывается диаметр провода.
#
# Author: Dogan Ibrahim
# File
: coil2.py
# Date
: August 2021
#=====================================================================
import math
L = float(input("Enter inductance (microhenries): "))
D = float(input("Enter Diameter (cm): "))
Len = float(input("Enter Length (cm): "))
#
# Теперь выполните расчет и отобразите N
#
N = (45 * D + 100 * Len) * L / (D * D)
N = math.sqrt(N)
print("Number of turns = %10.4f" %(N))
W = 10 * Len / N
print("Wire diameter (mm) = %10.4f" %(W))
Рис. 4.34: Листинг программы.
● 76
Chapter 4 • Amateur Radio Programs — Software Only
Рис. 4.35: Пример выполнения программы.
4.2.11 Смещение делителя напряжения на биполярном транзисторе (BJT)
В данном примере мы проанализируем постоянные напряжения и токи в схеме на
биполярном транзисторе, показанной на рис. 4.36. Пользователь вводит значения всех
резисторов, напряжения питания и значение коэффициента усиления по току транзистора β.
Цель этого примера — показать, как можно проводить анализ постоянного тока в схеме на
биполярном транзисторе, сконфигурированной, как на рис. 4.36.
Рис. 4.36: Схема на биполярном транзисторе.
Напряжения и токи, относящиеся к рис. 4.36, можно рассчитать следующим образом:
(4.24)
(4.25)
(4.26)
(4.27)
(4.28)
● 77
Raspberry Pi Pico for Radio Amateurs
(4.29)
(4.30)
(4.31)
(4.32)
Обратите внимание, что базовый ток обычно мал по сравнению с коллекторным током.
Следовательно, в большинстве расчетов уравнения (4.28), (4.29) и (4.30) заменяются близким
приближением:
На рис. 4.37 показан листинг программы (program:bias.py). Программа отображает заголовок,
а затем считывает значения двух резисторов, напряжения питания и коэффициента усиления
по току β («B») транзистора. Затем она вычисляет и отображает все напряжения и токи,
показанные в уравнениях (4.24) – (4.32). Типичный пример работы программы показан на
рисунке 4.38 со следующими значениями компонентов:
Vcc = 12 В
RB1 = 30,000 Ом
RB2 = 10,000 Ом
RC = 1000 Ом
RE = 1000 Ом
β = 100
#=================================================
#
Смещение делителя напряжения
#
===========================
#
# Эта программа считает смещение делителя напряжения
#
# Author: Dogan Ibrahim
# File
: bias.py
# Date
: August 2021
#=================================================
print("Voltage Divider Biassed Transistor Analysis")
print("===========================================")
● 78
Chapter 4 • Amateur Radio Programs — Software Only
#
# Прочитайте значения компонентов.
#
Vcc = float(input("Enter supply voltage (Volts): "))
RB1 = float(input("Enter RB1 (Ohms): "))
RB2 = float(input("Enter RB2 (ohms): "))
RC = float(input("Enter RC (Ohms): "))
RE = float(input("Enter RE (Ohms): "))
B = float(input("Enter current gain(B): "))
#
# Расчёт
#
Vb = 0.7
VB = Vcc * (RB2 / (RB1 + RB2))
IB1 = (Vcc - VB) / RB1
IE = (VB - Vb) / RE
RB = RB1 * RB2 / (RB1 + RB2)
IB = (VB - Vb) / (RB + RE * (B + 1))
IB2 = IB1 - IB
IC = IE - IB
VCE =
Vcc - (IC * RC + IE * RE)
VE = IE * RE
VC = Vcc - RC * IC
IB1 = 1000.0 * IB1
IB2 = 1000.0 * IB2
IE = 1000.0 * IE
IC = 1000.0 * IC
IB = 1000.0 * IB
#
# Отобразить результаты
#
print("\nVB=%7.3f V\nVCE=%7.3f V\nVE=%7.3f V\nVC=%7.3f V" %(VB,VCE,VE,VC))
print("\nIB1=%7.3f mA\nIB2=%7.3f mA\nIB=%7.3f mA\nIC=%7.3f mA\nIE=%7.3f mA"
%(IB1,IB2,IB,IC,IE))
Рис. 4.37: Листинг программы.
● 79
Raspberry Pi Pico for Radio Amateurs
Рис. 4.38: Типичный запуск программы.
4.2.12 Проектирование схемы усилителя на биполярном транзисторе
с общим эмиттером
В этом примере мы разработаем схему усилителя на одном транзисторе с общим
эмиттером с заданным напряжением питания и коэффициентом усиления по напряжению.
Цель этого примера — показать, как можно спроектировать однокаскадный усилитель с
общим эмиттером с помощью языка программирования Python.
Схема однокаскадного усилителя с общим эмиттером показана на рис. 4.39. Параметры
переменного тока этой схемы усилителя можно рассчитать по следующей формуле (см.
модель Hybrid Pi):
гдe
● 80
на требуемой частоте –3 дБ
Chapter 4 • Amateur Radio Programs — Software Only
где
гдe
на требуемой частоте –3 дБ
на требуемой частоте –3 дБ
Разработка начинается с определения требуемого коэффициента усиления по напряжению,
или входного напряжения и требуемого выходного напряжения. Обычно указывается
напряжение питания. Сначала необходимо подобрать значения резисторов для смещения
транзистора и обеспечения требуемого коэффициента усиления. Вкратце, шаги следующие:
• используя входное и требуемое выходное напряжения, рассчитайте
требуемый коэффициент усиления по напряжению
• выберите ток коллектора около 2 мА
• примите VCE равным Vcc/2.
• выберите значение RL. Предполагая, что коэффициент усиления без резисторов
источника и нагрузки при комнатной температуре равен RL×IE/25, выберите RL
таким образом, чтобы коэффициент усиления был на 30% выше требуемого знач.
• выберите значение RE (предполагая, что IE=Ic) из уравнения
Vcc=IcR L+VCE+IcRE
• рассчитайте базовый ток по формуле IB/β
• рассчитайте базовое напряжение по формуле VB = 0,7 + IcRE
• предположим , что ток в R1 и R2 в 10 раз превышает базовый ток,
и рассчитайте подходящие значения для R1 и R2.
• рассчитайте входное и выходное импедансы
• убедитесь, что общее усиление соответствует требованиям;
если нет, вернитесь назад и пересчитайте Ic, RL или RE
• рассчитайте подходящие значения для C1, C2 и CE.
Рис. 4.39: Схема усилителя с общим эмиттером.Ы
На рис. 4.40 показан листинг программы (program:amplifier.py). В начале программы
отображается заголовок.
● 81
Raspberry Pi Pico for Radio Amateurs
#=====================================================
# Проектирование однокаскадного усилителя с общим эмиттером
#
============================================
#
# Эта программа проектирует усилитель с общим эмиттером
#
#
# Author: Dogan Ibrahim
# File
: amplifier.py
# Date
: August 2021
#======================================================
import math
print("Single Stage Common Emitter Amplifier Design")
print("============================================")
#
# Чтение значений компонентов
#
Vcc = float(input("Enter supply voltage (Volts): "))
Vin = float(input("Enter Vin (Volts): "))
Vout = float(input("Enter Vout (Volts): "))
RS = float(input("Enter Rs (ohms): "))
RL = float(input("Enter RL (Ohms): "))
f = float(input("Enter lowest frequency to amplify (Hz): "))
B = float(input("Enter current ratio (B): "))
#
# Расчёт
#
Gr = Vout / Vin
# Коэффициент усиления
IC = 2 # IC=2 мА
Ge = Gr * (1.3)
# Расчетный коэффициент усиления на 30% выше
RC = Ge * 25 / IC
# Сопротивление коллектора
RCRL = (RC * RL) / (RC + RL)
re = 25.0 / IC
Rinbase = B * re
# Базовое сопротивление
G1 = RCRL / re
# G1
VCE = Vcc / 2
# VCE
IC = IC / 1000.0
RE = (Vcc - RC * IC - VCE) / IC
# RE
VB = 0.7 + IC * RE
IB = IC / B
IR1R2 = 10.0 * IB
R2 = VB / IR1R2
R1 = (Vcc - VB) / IR1R2
RB = (R1 * R2) / (R1 + R2)
● 82
# 10-кратный базовый ток
Chapter 4 • Amateur Radio Programs — Software Only
Zi = (RB * Rinbase) / (RB + Rinbase)
G2 = Zi / (RS + Zi)
G = G1 * G2
XC = Zi / 10.0
C1 = 1000000.0 / (2 * math.pi * f * XC)
Zo = RCRL
XC = Zo / 10.0
C2 = 1000000.0 / (2 * math.pi * f * XC)
XC = RE / 10.0
CE = 1000000.0 / (2 * math.pi * f * XC)
#
# Отображение результатов
#
print("\nRESULTS:")
print("=======")
print("Gain=%7.3f\nIC=%7.3f mA\nIB=%7.3f mA" %(G,IC*1000.0,IB*1000.0))
print("\nVcc=%7.3f V\nVB=%7.3f V\nVCE=%7.3f V" %(Vcc,VB,VCE))
print("\nR1=%7.3f Ohm\nR2=%7.3f Ohm\nRC=%7.3f Ohm\nRE=%7.3f Ohm" %(R1,R2,RC,RE))
print("\nC1=%7.3f uF\nC2=%7.3f uF\nCE=%7.3f uF" %(C1,C2,CE))
print("\nZi=%7.3f Ohm\nZo=%7.3f Ohm" %(Zi,Zo))
Рис. 4.40: Листинг программы.
Пример выполнения программы показан на рис. 4.41. В этом примере были приняты
следующие параметры:
Vin = 0.010 V
Vout = 0.4 V
Rs = 100 ohm
RL = 15 kohm
fl = 40 Hz
Vcc = 12 V
β = 100
Очевидно, что требуемый коэффициент усиления транзистора (без учета сопротивления
истока и нагрузки) составляет 0,4 В / 0,010 В = 40.
● 83
Raspberry Pi Pico for Radio Amateurs
Рис. 4.41: Пример выполнения программы.
4.2.13 Проектирование активных фильтров нижних частот
Фильтры нижних частот широко используются в любительской радиосвязи. В этом примере
мы разработаем активный фильтр нижних частот второго порядка. Пользователи вводят
частоту среза фильтра, и программа рассчитает и отобразит значения компонентов.
Существует несколько типов активных фильтров нижних частот второго порядка. В данном
примере используется хорошо известный фильтр типа Саллена-Кея, принципиальная схема
которого показана на рис. 4.42. Фильтр состоит из двух конденсаторов и двух резисторов. Этот тип
фильтра имеет единичное усиление в полосе пропускания.
Рис. 4.42: Фильтр нижних частот второго порядка.
Можно проектировать фильтры типа Саллена-Кея с более высоким коэффициентом
усиления, но следует проявлять осторожность, поскольку фильтры с высоким
коэффициентом усиления могут легко стать нестабильными и начать колебаться, что
приводит к значительному перерегулированию во временной характеристике и высокому
коэффициенту усиления на частотах среза. Добротность (Q-фактор) фильтра определяет его
качество, то есть демпфирование отклика. Для фильтров нижних частот значение Q должно
быть равно 0,707. Более высокие значения Q могут вызвать нестабильность и
перерегулирование во временной и частотной характеристиках. Другим параметром,
используемым при проектировании фильтра, является коэффициент демпфирования,
обозначаемый ξ. Он связан с добротностью (Q-фактором) следующим уравнением:
● 84
Chapter 4 • Amateur Radio Programs — Software Only
Идеальное значение ξ также равно 0,707. Более низкие значения ξ приводят к колебаниям и
нестабильности в разработанной схеме. Для поддержания стабильности коэффициент
усиления активного фильтра не должен превышать 3. Связь между коэффициентом усиления
и добротностью Q выражается следующим образом:
На рис. 4.43 показана частотная характеристика фильтра для различных значений ξ. Из этого
рисунка видно, что при ξ = 0,707 получается плоская характеристика.
Рис. 4.43: Частотная характеристика фильтра для различных значений ξ.
Частота среза фильтра на рис. 4.42 определяется следующим образом:
Для того чтобы гарантировать, что Q = 0,707, необходимо выполнить
следующее условие:
Пусть R1 = R2 = R, и C1/C2 = n, тогда необходимо убедиться, что
C1 / C2 >= 4Q2, i.e., C1 / C2 >= 2
or C2 / C1 <= 0.5
Тогда уравнение проектирования фильтра принимает вид:
или,
● 85
Raspberry Pi Pico for Radio Amateurs
Этапы проектирования следующие:
• определите частоту среза фильтра
• выберите значение для C2
• выберите значение для C1, убедившись, что C1/C2 >= 2.
Для Q = 0,707 выберите C1/C2 = 2
• Рассчитайте требуемое R
На рис. 4.44 показан листинг программы (program:lowpass.py). В начале программы
отображается заголовок, и пользователю необходимо ввести частоту среза фильтра, а также
значения C1 и C2 в микрофарадах. Программа вычисляет и отображает необходимые
резисторы, проверяя выполнение вышеуказанного неравенства. Затем пользователю
предлагается ввести фактические физические значения резисторов, которые будут
использоваться, и отображается фактическая частота среза при использовании этих
резисторов. Если пользователь не удовлетворен вычисленной частотой среза, программа
перезапускается, чтобы пользователь мог выбрать новые значения конденсаторов.
#=====================================================
# Проектирование активного фильтра нижних частот второго порядка
#
==========================================
#
# Фильтр нижних частот второго порядка.
#
# Author: Dogan Ibrahim
# File
: lowpass.py
# Date
: August 2021
#======================================================
import math
yn = 'n'
while yn == 'n':
print("Second Order Low-Pass Active Filter Design")
print("==========================================")
#
# Прочитайте частоту среза и C1, C2.
#
C1 = 1
C2 = 1
f = float(input("Enter the cut-off frequency (Hz): "))
while C1/C2 < 2:
C2 = float(input("Enter C2 (microfards): "))
C = 2 * C2
C1 = float(input("Enter C1 (microfarads) C1 >= %d : " %(C)))
C1F = C1 / 1000000.0
C2F = C2 / 1000000.0
● 86
Chapter 4 • Amateur Radio Programs — Software Only
#
# Расчеты
#
n = C1F / C2F
r = 2 * math.pi * f * C2F * math.sqrt(n)
R = 1 / r
#
# Отобразить результаты
#
print("\nRESULTS:")
print("=======")
print("C1=%7.3f uF\nC2=%7.3f uF\nR1=%7.3f Ohm\nR2=%7.3f Ohm" %(C1,C2,R,R))
print("\nEnter the actual physical resistors to be used:")
Rnew = float(input("Enter R1, R2 (Ohms): "))
fn = 2 * math.pi * Rnew * C2F * math.sqrt(n)
fnew = 1 / fn
print("Actual cut-off requency = %7.3f Hz" %(fnew))
yn = input("Are you happy with the actual cut-off frequecy (yn)? ")
yn = yn.lower()
Рис. 4.44: Листинг программы.
Пример выполнения программы показан на рис. 4.45. В этом примере
использовались следующие параметры:
Частота среза = 1000 Гц C2 = 12 мкФ
C1 = 6 мкФ
Рис. 4.45: Пример выполнения программы.
● 87
Raspberry Pi Pico for Radio Amateurs
Значения резисторов рассчитаны как R1 = R2 = 18,759 Ом. Выбор ближайшего физического
значения 18 Ом дает частоту среза 1042,033 Гц. Мы принимаем это значение и отвечаем y,
чтобы завершить программу. Приложение, доступное по следующей ссылке, можно
использовать для отображения частотной характеристики, добротности и т. д. фильтра
нижних частот типа Саллена-Ки:
http://sim.okawa-denshi.jp/en/OPstool.php
Использование этого приложения, результирующая передаточная функция, добротность,
коэффициент демпфирования, частотная и фазовая характеристики разработанного фильтра
с новыми резисторами показаны на рисунках 4.46 и 4.47.
Рис.4.46: Технические характеристики разработанного фильтра.
Рис.4.47: Частотная и фазовая характеристики разработанного фильтра.
● 88
Chapter 4 • Amateur Radio Programs — Software Only
Вышеприведенное приложение также показывает переходную характеристику
разработанного фильтра. Это показано на рис. 4.48.
Рис.4.48: Временная характеристика спроектированного фильтра.
Мы можем спроектировать фильтры более высокого порядка, каскадируя базовую
секцию второго порядка, приведенную в этом примере.
4.2.14 Длина четвертьволновой вертикальной антенны
На рис.4.49 показана программа Raspberry Pi Pico под названием «antenna»,
которую можно использовать для расчета длины четвертьволновой вертикальной
антенны с учетом рабочей частоты. Для четвертьволновой вертикальной антенны с
плоской земной поверхностью радиалы на 12% длиннее и расположены под углом
45º к горизонтальной плоскости. Пример запуска программы показан на рис. 4.50.
Разработанная антенна показана на рис. 4.51.
print("Quarter-wave antenna calculator")
F = float(input("Enter frequency in MHz: "))
Lengthft = 234/F
Radialft = Lengthft * 1.12
Lengthcm = 7150/F
Radialcm = Lengthcm * 1.12
print("Antenna length = %f feet or %f cm" %(Lengthft, Lengthcm))
print("Radial length = %f feet or %f cm" %(Radialft, Radialcm))
Рис.4.49: Листинг программы.
Рис.4.50: Пример запуска программы.
● 89
Raspberry Pi Pico for Radio Amateurs
Рис. 4.51: Разработанная антенна.
4.2.15 Микросхема LM555 (моностабильная/бистабильная/астабильная)
Микросхема LM555/NE555 — чрезвычайно популярный чип, используемый в схемах с
моностабильными и астабильными генераторами. Обычно он используется как
моностабильный генератор для генерации задержек или как астабильный генератор для
генерации прямоугольных сигналов. В этом разделе мы представим программу, которую
можно использовать для проектирования схем с моностабильными и астабильными
генераторами на основе LM555.
Схема с моностабильным генератором
На рис. 4.52 показана принципиальная схема моностабильного генератора на основе
LM555. На вывод 2 микросхемы подается импульс, переходящий из высокого уровня в
низкий. На выходном выводе 3 генерируется импульс. Длительность T этого импульса
устанавливается резисторами R и конденсатором C по следующей формуле:
T = 1.1RC
Рис. 4.52: Моностабильная схема.
Автоколебательная схема
На рис. 4.53 показана принципиальная схема автоколебательного генератора на
микросхеме 555. Период T выходного прямоугольного сигнала задается компонентами R1,
R2 и C1 и определяется формулой:
T = Th + Tl, где Th — время высокого уровня выходного сигнала,
аTl — время низкого уровня выходного сигнала.
● 90
Chapter 4 • Amateur Radio Programs — Software Only
и,
Th = 0.7 × (R1 + R2) × C1Tl = 0.7 × R2 × C1
Используя приведенную выше формулу, период выходного сигнала определяется
следующим образом:
T = 0.7 × (R1 + 2R2) × C1
А частота определяется следующим образом:
Коэффициент заполнения D формы сигнала — это отношение времени включения к периоду, и он
определяется формулой:
D = 100 × Th / T % или,
D = (R1 + R2) / (R1 + 2R2) × 100%
Обратите внимание, что коэффициент заполнения 50% невозможен. Для коэффициента
заполнения, максимально близкого к 50%, выберите большое значение R2.
Рис. 4.53: Автоколебательная схема.
На рис. 4.54 показан листинг программы (программа: NE555). В начале программы
пользователю предлагается ввести m (моностабильный) или (астабильный). Если необходимо
спроектировать моностабильную схему, то считываются значения t и C, вычисляется и
отображается R. Если необходимо спроектировать астабильную схему, то считываются
значения f, C1 и R2, вычисляется и отображается R1.
● 91
Raspberry Pi Pico for Radio Amateurs
print("555 MONOSTABLE-ASTABLE DESIGN")
mode = input("Monostable(m) or Astable (a) ?: ")
if mode == 'm':
t = float(input("Required output pulse width (seconds): "))
C = float(input("Enter capacitor C (uF): "))
C = C / 1000000
R = t / (1.1 * C)
print("Required resistor value is (Ohms): %5.2f" %(R))
elif mode == 'a':
f = float(input("Required frequency (Hz): "))
C1 = float(input("Enter capacitor C1 (uF): "))
C1 = C1 / 1000000
R2 = float(input("Enter R2 (Ohms): "))
R1 = 1.44 / (f * C1) - 2 * R2
print("Required resistor R1 value is (Ohms): %5.2f" %(R1))
D = 100 * (R1 + R2) / (R1 + 2 * R2)
print("Duty cycle = %3.2f percent" %(D))
Рис. 4.54: Листинг программы.
На рис. 4.55 показана схема автоколебательного контура с частотой 1 Гц, емкостью
конденсатора C 1 мкФ и сопротивлением резистора R2, выбранным равным 680 кОм.
Рис. 4.55: Пример проектирования автоколебательной схемы.
4.2.16 Проектирование пассивного низкочастотного фильтра Баттерворта
Пассивные фильтры используются во многих коммуникационных схемах. В этом разделе
представлена программа для проектирования пассивных фильтров нижних частот типа
Баттерворта, содержащих конденсаторы и индукторы.
На рис. 4.56 показана частотная характеристика фильтров нижних частот
типа Баттерворта различных порядков.
● 92
Chapter 4 • Amateur Radio Programs — Software Only
Рис. 4.56: Частотная характеристика фильтров Баттерворта.
Фильтры нижних частот Баттерворта могут быть реализованы с использованием топологии Кауэра, в
которой в качестве компонентов используются индукторы и конденсаторы. Эта топология
предполагает сопротивление источника и нагрузки 1 Ом и частоту 1 рад/с. Как показано ниже,
существуют две топологии в зависимости от того, какой из компонентов — индуктор или
параллельный конденсатор — используется первым на конце источника.
Tип 1
На рис. 4.57 показана топология типа 1.
Рис. 4.57: Топология типа 1.
Коэффициенты фильтра нижних частот Баттерворта задаются следующим образом:
k — чётное число
k — нечётное число
Тип 2
На рис. 4.58 показана топология типа 2.
● 93
Raspberry Pi Pico for Radio Amateurs
Рис. 4.58. Топология типа 2.
Коэффициенты фильтра нижних частот Баттерворта задаются следующим образом:
k is odd
k is even
После определения значений LandC необходимо масштабировать их до требуемого
сопротивления источника, сопротивления нагрузки и частоты среза, применив следующие
преобразования:
L L × R / Wc
C C / (Wc × R)
Где R — сопротивление источника и нагрузки (они равны), а Wc = 2 × π × f, где f — требуемая
частота среза. Обратите внимание, что Wc — это компьютерное обозначение для ωc.
На рис. 4.59 показан листинг программы (программа: LPPassive). В начале программы
пользователю необходимо выбрать тип топологии, а затем ввести требуемое сопротивление
источника и нагрузки, порядок фильтра и требуемую частоту среза. Программа вычисляет и
отображает значения L и C для выбранной топологии.
#=================================================================
# ПРОЕКТИРОВАНИЕ ПАССИВНОГО ФИЛЬТРА НИЗКИХ ЧАСТОТ БАТТЕРВОРТА
#
# Эта программа отображает значения L и C для фильтра нижних частот,
# порядок, частота среза и сопротивление источника (нагрузки) которого заданы.
#
# Author: Dogan Ibrahim
# File
: LPPassive.py
# Date
: August 2021
#=================================================================
import math
print("Passive Butterworth Low-Pass Filter Design")
topology = int(input("Choose topology Type 1 (1) or Type 2 (2): "))
n = int(input("Enter filter order: "))
R = int(input("Enter source and load resistance (Ohms): "))
f = int(input("Enter cut-off frequency (Hz): "))
w = 2 * 3.14159 * f
● 94
Chapter 4 • Amateur Radio Programs — Software Only
if topology == 1:
for k in range(1, n+1):
m = (2 * k - 1) * 3.14159 / ( 2 * n)
if (k % 2) == 0:
C = 2 * math.sin(m)
CC = 1000000 * C / (w * R)
print("C%d = %f uF" %(k, CC))
else:
L = 2 * math.sin(m)
LL = 1000 * L * R / w
print("L%d = %f mH" %(k, LL))
elif topology == 2:
for k in range(1, n+1):
m = (2 * k - 1) * 3.14159 / ( 2 * n)
if (k % 2) == 0:
L = 2 * math.sin(m)
LL = 1000 * L * R / w
print("L%d = %f mH" %(k, LL))
else:
C = 2 * math.sin(m)
CC = 1000000 * C / (w * R)
print("C%d = %f uF" %(k, CC))
Рис. 4.59: Листинг программы.
На рис. 4.60 показан пример выходных данных проектирования пассивного фильтра нижних
частот Баттерворта 4-го порядка типа 1 с частотой среза 1000 Гц и сопротивлением источника
(нагрузки) 50 Ом. Схема разработанного фильтра показана на рис. 4.61.
Рис. 4.60: Пример выходных данных.
Рис. 4.61: Разработанная схема фильтра.
● 95
Raspberry Pi Pico for Radio Amateurs
4.2. Согласование импедансов
Согласование импедансов является важным понятием в приложениях, обеспечивающих
максимальную передачу мощности. Для максимальной передачи мощности сопротивление
источника и нагрузки должно быть одинаковым. В радиочастотных схемах обычно
используются комплексные импедансы источника и/или нагрузки с действительными частями и
реактивными сопротивлениями. Такие импедансы обычно согласуются на заданной частоте.
Согласование комплексных импедансов — непростая задача. В этом разделе представлена
программа, которая может быть использована для расчета необходимых значений индуктора и
конденсатора для согласования импеданса источника с импедансом нагрузки.
В этом разделе рассматриваются L-образные согласующие цепи. На рис. 4.62 (последовательное
соединение) и рис. 4.63 (последовательное соединение) показаны два типа схем согласования
импедансов. Здесь R1+jX1 — импеданс источника, а R2+jX2 — импеданс нагрузки.
Рис. 4.62: Схема согласования импедансов с последовательным шунтированием.
Рис. 4.63: Схема согласования импедансов
последовательно-параллельного соединения.
На рис. 4.64 показан листинг программы (программа:match). В начале программы
пользователь вводит импедансы источника и нагрузки, а также рабочую частоту.
Программа рассчитывает компоненты согласующей цепи и отображает их на
экране.
● 96
Chapter 4 • Amateur Radio Programs — Software Only
#=================================================================
#
СОГЛАСОВАНИЕ ИМПЕДАНСА
#
# Эта программа вычисляет индуктивность и емкость для согласования
# импеданса источника с нагрузкой на заданной частоте
#
# Author: Dogan Ibrahim
# Date
: August 2021
# File
: match.py
#=================================================================
R1=float(input("R1 (Ohm): "))
X1=float(input("X1 (Ohm): "))
R2=float(input("R2 (Ohm): "))
X2=float(input("X2 (Ohm): "))
f=float(input("freq (MHz): "))
w = 2 * 3141592 * f
if R1 * (R1 - R2) + X1 * X1 >= 0:
print("Shunt-Series Design")
xshu1=(R1*X2+R2*X1-R1*(X2-((R2*(R1**2-R2*R1+X1**2))/R1)**(1/2)))/(R1-R2)
xser1=X2-((R2*(R1**2-R2*R1+X1**2))/R1)**(1/2)
xshu2=(R1*X2+R2*X1-R1*(X2+((R2*(R1**2-R2*R1+X1**2))/R1)**(1/2)))/(R1-R2)
xser2=X2+((R2*(R1**2-R2*R1+X1**2))/R1)**(1/2)
Lshunt = 1E9 * xshu1 / w
print("shunt inductor=%f Ohm, %5.3f nH" %(xshu1, Lshunt))
Cseries = 1E12 / (w * xser2)
print("series capacitor=%f Ohm, %5.3f pF" %(xser2, Cseries))
print("OR")
Cshunt = -1E12 / (w * xshu2)
print("shunt capacitor=%f Ohm, %5.3f pF" %(xshu2, Cshunt))
Lseries = -1E9 * xser1 / w
print("series inductor=%f Ohm, %5.3f nH" %(xser1, Lseries))
elif R2 * (R2 - R1) + X2 * X2 >= 0:
print("Series-shunt Design")
xshu1=(R1*X2+(R1*R2*(R2**2-R1*R2+X2**2))**(1/2))/(R1-R2)
xser1=-(R2*X1-(R1*R2*(R2**2-R1*R2+X2**2))**(1/2))/R2
xshu2=(R1*X2-(R1*R2*(R2**2-R1*R2+X2**2))**(1/2))/(R1-R2)
xser2=-(R2*X1+(R1*R2*(R2**2-R1*R2+X2**2))**(1/2))/R2
Lshunt = -1E9 * xshu1 / w
print("shunt inductor=%f Ohm, %5.3f nH" %(xshu1, Lshunt))
● 97
Raspberry Pi Pico for Radio Amateurs
Cseries = -1E12 / (w * xser2)
print("series capacitor=%f Ohm, %5.3f pF" %(xser2, Cseries))
print("OR")
Cshunt = 1E12 / (w * xshu2)
print("shunt capacitor=%f Ohm, %5.3f pF" %(xshu2, Cshunt))
Lseries = 1E9 * xser1 / w
print("series inductor=%f Ohm, %5.3f nH" %(xser1, Lseries))
Рис. 4.64: Листинг программы.
На рис. 4.65 показан пример схемы. Обратите внимание, что существует два решения задачи,
и оба решения отображаются программой. Разработанная схема показана на рис. 4.66.
Рис. 4.65: Пример конструкции.
Рис. 4.66: Схема согласования импедансов.
● 98
Chapter 5 • Simple Hardware-Based Projects
Глава 5 • Простые аппаратные проекты
5.1 Обзор
В этой главе мы будем разрабатывать простые аппаратные проекты с использованием
Raspberry Pi Pico, применяя текстовый редактор Thonny. В этих проектах Raspberry Pi Pico
подключается к USB-порту ПК. Цель этой главы — познакомить читателя с аппаратным
обеспечением Raspberry Pi Pico, а также показать, как можно разрабатывать простые
аппаратные проекты с использованием языка программирования MicroPython.
5.2 Проект 1: Мигание встроенного светодиода
В этом проекте встроенный светодиод будет мигать каждую секунду. Цель проекта —
ознакомить читателя с некоторыми основными операторами управления GPIO.
На рис. 5.1 показан листинг программы (Программа:LEDINT). В начале программы
импортируются модули machine и utime. Затем модуль 'LED' назначается на вывод порта
GP25 и настраивается как выход. Остальная часть программы выполняется в бесконечном
цикле, пока не будет остановлена пользователем. Внутри этого цикла светодиод включается
оператором LED.value(1). После задержки в одну секунду светодиод выключается оператором
LED.value(0). Функция utime.sleep(n) создает задержку в n секунд в программе.
#--------------------------------------------------------#
МИГАНИЕ ВСТРОЕННОГО СВЕТОДИОДА
#
===================================
#
# В этой программе встроенный светодиод (на GP25)
# мигает каждую секунду
#
# Author: Dogan Ibrahim
# File
: LEDINT.py
# Date
: August, 2021
#---------------------------------------------------------import machine
import utime
LED = machine.Pin(25, machine.Pin.OUT) # LED at GP25
while True:
#работать вечно
LED.value(1)
# LED включен
utime.sleep(1)
LED.value(0)
utime.sleep(1)
# подождите 1 секунду
# LED выключен
# подождите 1 секунду
Рис. 5.1: Программа: LEDINT.
● 99
Raspberry Pi Pico for Radio Amateurs
На рис. 5.1 модуль импорта машины импортирует другие функции в дополнение к Pin. Мы
можем упростить программу, импортировав только функции Pin, как показано на рис. 5.2
(Программа: LEDINT2). Возможно, вам потребуется остановить программу, выбрав «Запуск»,
а затем «Остановить/Перезапустить», прежде чем вы сможете сохранить новую программу,
если она уже запущена на Pico.
#--------------------------------------------------------#
МИГАНИЕ ВСТРОЕННОГО СВЕТОДИОДА
#
===================================
#
# В этой программе встроенный светодиод (на GP25) мигает
# каждую секунду. В этой версии импортируется только модуль Pin
#
# Author: Dogan Ibrahim
# File
: LEDINT2.py
# Date
: August, 2021
#---------------------------------------------------------from machine import Pin
import utime
LED = Pin(25, Pin.OUT)
while True:
LED.value(1)
utime.sleep(1)
LED.value(0)
utime.sleep(1)
# LED на GP25
# Работать вечно
# Светодиод включен
# Подождите 1 секунду
# Светодиод выключен
# Подождите 1 секунду
Рис. 5.2: Программа: LEDINT2.
.
Модуль machine поддерживает следующие функции (мы увидим, как использовать эти
функции в последующих главах):
•
•
•
•
•
•
•
•
● 100
Pin
Timer
ADC
I2C and Soft I2C
SPI and SoftSPI
WDT
PWM
UART
Chapter 5 • Simple Hardware-Based Projects
Параметры контакта можно повторно инициализировать с помощью следующей функции:
Pin.init(pin, mode, value, drive, at)
Где pin — номер контакта.
Параметр mode может принимать следующие значения:
Pin.IN
Pin.OUT
Pin.OPEN_DRAIN Pin.ALT
-
пин
пин
пин
пин
настроен как вход
настроен как выход
сконфигурирован как выход с открытым стоком
настроен как альтернативная функция
Параметр pull может принимать следующие значения:
NONE
- отсутствуют внутренние подтягивающие резисторы
Pin.PULL_UP
- внутренний подтягивающий резистор включен
Pin.PULL_DOWN - внутренний подтягивающий резистор включен
Параметр value действителен только для режимов Pin.OUT и Pin.OPEN_DRAIN и задает
начальное значение выходного контакта (если указано).
Параметр alt задает альтернативную функцию для контакта (зависит от порта). Этот параметр
действителен только для режимов PIN.ALT и PIN.ALT_OPEN_DRAIN.
Установить/сбросить значение контакта можно с помощью
одной из следующих функций:
Pin.value(1)
Pin.value(0)
- установить пин в логическое значение 1
- установить пин в логическое значение 0
К числу других полезных машинных функций относятся:
machine.reset()
- с
бросить устройство (аналогично
нажатию внешней кнопки RESET)
machine.reset_cause)
machine.disable_irq()
machine.enable_irq()
machine.freq()
-
вернуть причину сброса
отключить запросы прерываний
включить запросы прерываний
вернуть частоту процессора
5.3 Проект 2: Внешний мигающий светодиод
В этом проекте внешний светодиод подключен к Pico. Светодиод мигает каждую секунду, как и
в предыдущем проекте. Цель этого проекта — показать, как можно подключить внешний
светодиод к Pico.
На рис. 5.3 показана блок-схема проекта.
● 101
Raspberry Pi Pico for Radio Amateurs
Рис. 5.3: Блок-схема проекта.
Схема проекта показана на рис. 5.4, где светодиод подключен к выводу GP0
микроконтроллера Pico через токоограничивающий резистор.
Рис. 5.4: Схема проекта.
Светодиод может быть подключен как в режиме источника тока, так и в режиме стока тока. В
режиме источника тока (рис. 5.5) светодиод включается при подаче логического высокого
уровня на вывод порта. В режиме стока тока (рис. 5.6) светодиод включается при подаче
логического низкого уровня на вывод порта.
Рис. 5.5: Режим питания светодиода по току.
● 102
Chapter 5 • Simple Hardware-Based Projects
Рис. 5.6: Светодиод в режиме потребления тока.
Требуемое значение токоограничивающего резистора можно рассчитать следующим образом:
В режиме источника тока, предполагая, что выходное напряжение ВЫСОКОГО уровня
составляет +3,3 В, падение напряжения на светодиоде равно 2 В, а ток через светодиод
равен 3 мА, требуемое значение токоограничивающего резистора составляет:
R = (3,3 – 2) / 3 = 433 Ом. В качестве ближайшего действительного значения выберем 470 Ом.
На рис. 5.7 показан листинг программы (Program:ExtFlash.py).
#--------------------------------------------------------#
МИГАНИЕ ВНЕШНЕГО СВЕТОДИОДА
#
===============================
#
# В этой программе внешний светодиод подключается к выводу
# порта GP0 (вывод 1). Светодиод мигает каждую секунду
#
# Author: Dogan Ibrahim
# File
: ExtFlash.py
# Date
: August, 2021
#---------------------------------------------------------from machine import Pin
import utime
LED = Pin(0, Pin.OUT)
while True:
LED.value(1)
utime.sleep(1)
LED.value(0)
utime.sleep(1)
# LED на GP0
# работать вечно
# LED включен
# Подождите 1 секунду
# LED выключен
# Подождите 1 секунду
Рис. 5.7: Программа: ExtFlash.py..
● 103
Raspberry Pi Pico for Radio Amateurs
На рис. 5.8 показана схема Fritzing проекта, построенного на макетной плате.
Рис. 5.8: Проект, собранный на макетной плате.
5.4 Проект 3: Изменение частоты мигания светодиода с помощью
прерываний от кнопок
В этом проекте внешний светодиод подключен к выводу GP0 платы Pico. Кроме того, две
кнопки подключены к выводам GP1 и GP2. В начале программы светодиод мигает каждую
секунду. Кнопка на выводе GP1 называется Faster, и нажатие этой кнопки заставляет
светодиод мигать быстрее. Аналогично, кнопка на выводе GP2 называется Slower, и
нажатие этой кнопки заставляет светодиод мигать медленнее. Цель этого проекта —
показать, как можно подключать кнопки к Pico и как можно считывать состояние
включения/выключения кнопки. Проект также демонстрирует, как использовать внешние
прерывания.
Рис. 5.9 показывает блок-схему проекта.
Рис. 5.9. Блок-схема проекта.
Схема проекта показана на рис. 5.10. Светодиод подключен через токоограничивающий
резистор 470 Ом. Две кнопки подключены через резисторы 10 кОм.
● 104
Chapter 5 • Simple Hardware-Based Projects
По умолчанию кнопки находятся в логическом состоянии 1, которое подтянуто к
резисторам. Нажатие кнопки изменяет ее выходное состояние на логический ноль.
Рис. 5.10: Схема проекта.
На рис. 5.11 показан листинг программы (Программа: LEDrate). В начале программы светодиод
назначается на вывод GP0, а кнопки Faster и Slower — на порты GP1 и GP2 соответственно.
Частота мигания по умолчанию установлена на одну секунду и хранится в переменной dly.
Программа основана на внешних прерываниях. Нажатие любой из кнопок создает прерывание.
Например, прерывание для кнопки Faster настраивается с помощью следующего вызова
функции:
Faster.irq(handler=Flash_Faster, trigger=Faster.IRQ_FALLING)
Faster.irq(handler=Flash_Faster, trigger=Faster.IRQ_FALLING)Где Flash_Faster — это имя
подпрограммы обработки прерывания, в которой задержка dly уменьшается. Прерывание
настроено на спад фронта сигнала кнопки, т.е. при нажатии кнопки (нормальное состояние
кнопок — логическая единица, подтянутая резисторами). Внутри подпрограммы обработки
прерывания Flash_Faster переменная dly объявлена как глобальная, чтобы к ней можно было
получить доступ. Затем ее значение уменьшается на 100 мс (0,1 секунды). Подпрограмма
обработки прерывания для кнопки Slow выполняется аналогично, где задержка увеличивается
на 100 мс каждый раз при нажатии кнопки.
Другие внешние режимы прерывания:
Pin.IRQ_FALLING
Pin.IRQ_RISING
Pin.IRQ_LOW_LEVEL
Pin.IRQ_HIGH_LEVEL
- прерывание
по спадающему фронту (от высокого уровня к низкому)
- прерывание
по восходящему фронту (от низкого уровня квысокому)
- прерывание по низкому уровню
- прерывание по высокому уровню
● 105
Raspberry Pi Pico for Radio Amateurs
Указанные выше значения можно объединить с помощью операции OR для запуска
нескольких событий. Также можно указать приоритет прерывания с помощью
ключевого слова priority, где более высокие значения соответствуют более
высоким приоритетам.
Параметр interruptwake может быть задан со значениями None, machine.IDLE,
machine.SLEEP или machine.DEEPSLEEP.
Кроме того, можно указать параметр hard со значениями False или True. Если этот
параметрустановлен в True, используются аппаратные прерывания, которые имеют более
быструю реакцию.
#--------------------------------------------------------# ИЗМЕНЕНИЕ ЧАСТОТЫ МИГАНИИ СВЕТОДИОДА
#
==========================================
#
# В этой программе к Pico подключены внешний светодиод и две кнопки.
# Нажатие кнопки Faster заставляет светодиод мигать быстрее,
# а нажатие кнопки Slower — медленнее.
#
# Author: Dogan Ibrahim
# File
: LEDrate.py
# Date
: August, 2021
#---------------------------------------------------------from machine import Pin
import utime
LED = Pin(0, Pin.OUT)
# Светодиод на выводе GP0
Faster = Pin(1, Pin.IN)
# Быстрее на выводе GP1
Slower = Pin(2, Pin.IN)
# Медленнее на выводе GP2
dly = 1.0
# Задержка по умолчанию
#
# Это подпрограмма обработки прерывания. При нажатии кнопки
# Faster программа переходит сюда и уменьшает # delay,
# чтобы ускорить мигание.
#
def Flash_Faster(Faster):
global dly
dly = dly - 0.1
#
# Это подпрограмма обработки прерывания. При нажатии кнопки
# Slower программа переходит сюда и увеличивает
# delay, чтобы замедлить мигание.
#
def Flash_Slower(Slower):
global dly
● 106
Chapter 5 • Simple Hardware-Based Projects
dly = dly + 0.1
#
# Настройка внешних прерываний
#
Faster.irq(handler=Flash_Faster,trigger=Faster.IRQ_FALLING)
Slower.irq(handler=Flash_Slower,trigger=Slower.IRQ_FALLING)
#
# Основная программа loop
#
while True:
LED.value(1)
# Светодиод включен
utime.sleep(dly)
# Задержка
LED.value(0)
# Светодиод выключен
utime.sleep(dly)
# Задержка
Рис. 5.11: Программа: LEDrate.
.
На рис. 5.12 показан проект, собранный на макетной плате.
Рис. 5.12: Проект, собранный на макетной плате.
Использование внутренних подтягивающих резисторов
Мы можем упростить схему на рис. 5.10, удалив внешние резисторы и используя внутренние
подтягивающие резисторы. Упрощенная схема показана на рис. 5.13. Модифицированный
листинг программы (Program:LEDrate2) показан на рис. 5.14, где в операторы конфигурации
входа добавлена опция pull = Pin.PULL__UP.
● 107
Raspberry Pi Pico for Radio Amateurs
Рис. 5.13: Модифицированная принципиальная схема.
#--------------------------------------------------------#
ИЗМЕНЕНИЕ ЧАСТОТЫ МИГАНИИ СВЕТОДИОДА
#
========================================
#
# В этой программе к Pico подключены внешний светодиод и две кнопки.
# Нажатие кнопки Faster ускоряет мигание светодиода,
# а нажатие кнопки Slower замедляет мигание светодиода.
# В этой модифицированной версии используются внутренние подтягивающие резисторы.
#
# Author: Dogan Ibrahim
# File
: LEDrate2.py
# Date
: August, 2021
#---------------------------------------------------------from machine import Pin
import utime
LED = Pin(0, Pin.OUT)
Faster = Pin(1, Pin.IN, pull=Pin.PULL_UP)
Slower = Pin(2, Pin.IN, pull=Pin.PULL_UP)
dly = 1.0
#
# Это подпрограмма обработки прерываний. При каждом нажатии кнопки
# Faster программа переходит сюда и уменьшает
# задержку, чтобы ускорить мигание.
#
def Flash_Faster(Faster):
global dly
dly = dly - 0.1
● 108
Chapter 5 • Simple Hardware-Based Projects
#
# Это подпрограмма обработки прерываний. При каждом нажатии кнопки
# Slower программа переходит сюда и увеличивает
# delay, чтобы замедлить мигание.
#
def Flash_Slower(Slower):
global dly
dly = dly + 0.1
#
# Настройте внешние прерывания.
#
Faster.irq(handler=Flash_Faster,trigger=Faster.IRQ_FALLING)
Slower.irq(handler=Flash_Slower,trigger=Slower.IRQ_FALLING)
#
# Основная программа loop
#
while True:
LED.value(1)
utime.sleep(dly)
LED.value(0)
utime.sleep(dly)
#
#
#
#
Светодиод включен
Задержка
Светодиод выключен
Задержка
Рис. 5.14: Программа: LEDrate2.
5.5 Проект 4: Счетчик по двоичному коду
В этом проекте к Pico подключено 8 светодиодов. Светодиоды считают в двоичном коде от 0
до 255, как показано на рис. 5.15, с задержкой в одну секунду между каждым счетом. Цель
этого проекта — показать, как можно объединить группу выводов порта и использовать их в
качестве параллельного порта.
Рис. 5.15: Двоичные счетные светодиоды.
● 109
Raspberry Pi Pico for Radio Amateurs
На рис. 5.16 показана блок-схема проекта. Схема цепи проекта показана на рис. 5.17.
Светодиоды подключены к Pico через токоограничивающие резисторы сопротивлением 470
Ом.
Рис. 5.16: Блок-схема проекта.
Рис. 5.17: Схема проекта.
На рис. 5.18 показан листинг программы (Program: LEDCount). Все 8 портов GPIO,
используемых в проекте, настроены как выходы с помощью функции Configuration_Port.
Обратите внимание, что функция Configuration_Port является общей и listDIR задает
направления выводов GPIO. "O" задает выход, а "I" — вход. Затем формируется цикл, который
выполняется бесконечно, и внутри этого цикла светодиоды отсчитывают единицу в двоичном
представлении. В качестве счетчика используется переменная cn. Функция Port_Output
используется для управления светодиодами. Эта функция может принимать целые числа от 0
до 255 и преобразует входное число (x) в двоичное представление с помощью встроенной
функции bin. Затем из выходной строки b удаляются символы "0b" (функция bin вставляет
символы "0b" в начало преобразованной строки). Затем преобразованная строка bi состоит из
8 символов путем вставки начальных нулей. Затем строка отправляется на PORTbit побитно,
начиная с наиболее значимого бита.
● 110
Chapter 5 • Simple Hardware-Based Projects
#--------------------------------------------------------#
Двоичный счёт, 8 светодиодов
# ==========================
#
# В этой программе к микроконтроллеру Pico подключено 8 светодиодов.
# Светодиоды каждую секунду ведут двоичный отсчет.
#
# Author: Dogan Ibrahim
# File
: LEDCount.py
# Date
: August, 2021
#---------------------------------------------------------from machine import Pin
import utime
PORT = [7, 6, 5, 4, 3,
2,
1,
0]
DIR = ["0","0","0","0","0","0","0","0"]
# Подключение портов
# Направления портов
L = [0]*8
#
# Эта функция настраивает выводы порта как выходы ("0")
# или как входы ("I")
#
def Configure_Port():
for i in range(0, 8):
if DIR[i] == "0":
L[i] = Pin(PORT[i], Pin.OUT)
else:
L[i] = Pin(PORT[i], Pin.IN)
return
#
# Эта функция отправляет 8-битные данные (от 0 до 255) на порт.
#
def Port_Output(x):
b = bin(x)
# Преобразовать в двоичный код
b = b.replace("0b", "")
# Удалить начальный "0b"
diff = 8 - len(b)
# Найти длину
for i in range (0, diff):
b = "0" + b
# вставить ведущую os
for i in range (0, 8):
if b[i] == "1":
L[i].value(1)
else:
L[i].value(0)
return
● 111
Raspberry Pi Pico for Radio Amateurs
#
# Настройте порт для всех выходов.
#
Configure_Port()
#
# Основной цикл программы. Счет в двоичном представлении каждую секунду.
#
cnt = 0
while True:
Port_Output(cnt)
# отправить счетчик на порт
utime.sleep(1)
# подождать 1 секунду
cnt = cnt + 1
# увеличить счетчик
if cnt > 255:
cnt = 0
.
Рис. 5.18: Программа: LEDCount.
На рис. 5.19 показан проект, собранный на макетной плате.
На рис. 5.19 показан проект, собранный на макетной плате.
5.6 Использование параллельных ЖК-дисплеев
В системах на базе микроконтроллеров обычно требуется взаимодействовать с системой,
например, для ввода параметра, изменения значения параметра или отображения выходных
данных измеряемой переменной.
● 112
Chapter 5 • Simple Hardware-Based Projects
Ввод данных в систему обычно осуществляется с помощью переключателя, небольшой
клавиатуры или полноценной клавиатуры. Отображение данных обычно происходит с
помощью индикатора, такого как один или несколько светодиодов, 7-сегментные дисплеи или
ЖК-дисплеи. ЖК-дисплеи обладают тем преимуществом, что могут отображать как
буквенно-цифровые, так и графические данные. Некоторые ЖК-дисплеи имеют длину 40 и
более символов и способны отображать данные в несколько строк. Другие ЖК-дисплеи могут
использоваться для отображения графических изображений (графические ЖК-дисплеи —
GLCD), таких как анимация. Некоторые дисплеи являются одноцветными или многоцветными,
в то время как другие имеют подсветку, позволяющую просматривать их в условиях
недостаточного освещения.
ЖК-дисплеи могут подключаться к микроконтроллеру либо параллельно, либо через
интерфейс I2C. Параллельные ЖК-дисплеи (например, Hitachi HD44780) подключаются с
использованием более чем одной линии данных и нескольких линий управления, при этом
данные передаются параллельно. Обычно используются 4 или 8 линий данных и две или
более линий управления. Использование 4-проводного соединения экономит выводы
ввода/вывода, но работает медленнее, поскольку данные передаются в два этапа.
ЖК-дисплеи на основе I2C, с другой стороны, подключаются к микроконтроллеру всего двумя
проводами: «данные» и «тактовый сигнал». ЖК-дисплеи на основе I2C, как правило, гораздо
проще в использовании и требуют меньше проводов, но стоят дороже, чем параллельные. В
этой главе мы будем изучать использование как параллельных, так и I2C-основанных
ЖК-дисплеев в проектах.
Программирование ЖК-дисплеев — сложная задача, требующая глубокого понимания
внутренних операций контроллеров ЖК-дисплеев, включая знание их точных требований к
синхронизации. К счастью, существует несколько библиотек, которые можно использовать для
упрощения работы как с параллельными, так и с последовательными ЖК-дисплеями.
ЖК-модуль HD44780
Хотя существует несколько типов ЖК-дисплеев, HD44780 по-прежнему остается одним из
самых популярных ЖК-модулей, используемых в промышленности и среди любителей (рис.
5.20). Этот модуль представляет собой буквенно-цифровой монохромный дисплей и
выпускается в различных размерах. Модули с 16 столбцами популярны в большинстве
небольших приложений, но также доступны и широко используются другие модули с 8, 20, 24,
32 или 40 столбцами. Хотя большинство ЖК-дисплеев имеют две строки (или ряда) в качестве
стандарта, можно приобрести модели с 1 или 4 строками. ЖК-дисплеи доступны со
стандартными 14-контактными разъемами, хотя на рынке также представлены 16-контактные
модули, обеспечивающие клеммы для подсветки. В таблице 3.4 приведена конфигурация
контактов и функции контактов 16-контактного ЖК-модуля. Ниже приведено краткое описание
функций контактов:
Pin no
Имя
Функция
1
VSS
Ground
2
VDD
+ Ve
3
VEE
Контрастность
4
RS
Выбор регистра
5
R/W
Чтение/запись
6
E
Включить
7
D0
Бит данных 0
● 113
Raspberry Pi Pico for Radio Amateurs
8
D1
Data bit 1
9
D2
Data bit 2
10
D3
Data bit 3
11
D4
Data bit 4
12
D5
Data bit 5
13
D6
Data bit 6
14
D7
Data bit 7
15
A
Анод подсветки (+)
16
K
Катод подсветки (GND)
Таблица 5.1: Распировка ЖК-модуля, совместимого с HD44780.
Рис. 5.20: Параллельный ЖК-дисплей, совместимый с HD44780.
VSS (вывод 1) и VDD (вывод 2) — это выводы заземления и питания соответственно.
Напряжение питания должно быть +5 В.VEE — это вывод 3, и это вывод управления
контрастностью, используемый для регулировки контрастности дисплея. Обычно к этому
выводу подключается рычаг потенциометра на 10 кОм, а два других вывода потенциометра
подключаются к выводу заземления и выводу питания. Контрастность дисплея регулируется
вращением вала потенциометра.
Контакт 4 — это контакт выбора регистра (RS). Когда этот контакт находится в низком
состоянии, данные, передаваемые на дисплей, рассматриваются как команды. Когда RS
находится в высоком состоянии, можно передавать символьные данные на дисплей и с
дисплея.
Контакт 5 — это линия чтения/записи (R/W). Этот контакт находится в низком состоянии для
записи команд или символьных данных в модуль ЖК-дисплея. Когда этот контакт находится в
высоком состоянии, можно считывать символьные данные или информацию о состоянии с
модуля. Обычно этот контакт постоянно находится в низком состоянии, что позволяет
отправлять команды или символьные данные на модуль ЖК-дисплея.
Вывод разрешения (E) — это вывод 6, который используется для инициирования передачи
команд или данных между модулем ЖК-дисплея и микроконтроллером. При записи на
дисплей данные передаются только при переходе этого вывода из высокого состояния в
низкое. При чтении с дисплея данные становятся доступными после перехода вывода
разрешения из низкого состояния в высокое, и эти данные остаются действительными до тех
пор, пока вывод разрешения находится в логическом высоком состоянии.
● 114
Chapter 5 • Simple Hardware-Based Projects
Пины с 7 по 14 представляют собой восемь линий шины данных (D0–D7). Данные могут
передаваться между микроконтроллером и ЖК-модулем как одним 8-битным байтом, так и
двумя 4-битными полубайтами. В последнем случае используются только верхние четыре
линии данных (D4–D7). Преимущество 4-битного режима заключается в том, что для связи с
ЖК-дисплеем требуется на четыре линии ввода-вывода меньше. Однако 4-битный режим
медленнее, поскольку данные передаются в два этапа. В этой книге мы используем только
4-битный интерфейс.
Пины 15 и 16 предназначены для управления яркостью фона. Для включения яркости фона
необходимо подключить резистор сопротивлением 220 Ом к выводу 15 и источнику питания
+5 В, а вывод 16 – к земле.
В 4-битном режиме используются следующие пины ЖК-дисплея: Линия R/W постоянно
подключена к земле. В этом режиме используются 6 контактов порта GPIO
микроконтроллера:
VSS, VDD, VEE, E, R/S, D4, D5, D6, D7
В следующем разделе мы создадим библиотеку функций ЖК-дисплея, которую можно
использовать для отправки данных и текста на стандартные ЖК-дисплеи типа HD44780.
5.7 Проект 5: Функции ЖК-дисплея — отображение текста
В этом проекте мы разработаем ряд функций для передачи данных и текста на ЖК-дисплеи
размером 16 × 2 символа. Целью данного проекта является разработка библиотеки функций
для управления ЖК-дисплеями. Эти функции можно использовать в проектах для передачи
текста и чисел на ЖК-дисплеи.
На рис. 5.21 показана блок-схема проекта.
Рис. 5.21: Блок-схема проекта.
Принципиальная схема проекта показана на рис. 5.22. ЖК-дисплей подключен к Pico с
помощью четырёх линий данных (D4–D7) и двух линий управления (E и R/S). Соединения
между ЖК-дисплеем и Pico следующие:
● 115
Raspberry Pi Pico for Radio Amateurs
LCD Pin
R/S
E
D4
D5
D6
D7
Pico Pin
GP1
GP0
GP2
GP3
GP4
GP5
Рис. 5.22: Схема проекта.
Контрастность ЖК-дисплея регулируется с помощью потенциометра на 10 кОм. Важно
подключить вывод R/W ЖК-дисплея к земле перед включением питания схемы.
На рис. 5.23 показан список функций (Программа:LCD). Соединения между LCD и Pico
определены в начале, и при желании их можно изменить. Остальные функции не следует
изменять для корректного управления LCD. Эти функции реализуют инициализацию и
управление LCD.
Доступны следующие функции управления LCD:
lcd_init: это функция инициализации LCD, и ее необходимо вызывать первой
перед вызовом любых других функций.
lcd_clear: очищает LCD
lcd_home: возвращает курсор в исходное положение (в верхнем левом углу).
lcd_cursor_blink: включает мигание курсора
lcd_cursor_on: включает видимый курсор
lcd_cursor_off: отключает видимый курсор
lcd_puts(s): отображает строку s
lcd_putch(c): отображает символ c
● 116
Chapter 5 • Simple Hardware-Based Projects
lcd_goto(col,row): Устанавливает курсор в указанный столбец и позицию.
(0,0) — левый угол ЖК-дисплея. Первая строка — строка 0, вторая — строка
1 и так далее.
#-------------------------------------------------#
ПАРАЛЛЕЛЬНЫЕ ФУНКЦИИ ЖК-ДИСПЛЕЯ
#
===================================
#
# Эти функции инициализируют и управляют ЖК-дисплеем.
#
# Author: Dogan Ibrahim
# File
: LCD
# Date
: August, 2021
#-------------------------------------------------from machine import Pin
import utime
EN = Pin(0, Pin.OUT)
RS = Pin(1, Pin.OUT)
D4 = Pin(2, Pin.OUT)
D5 = Pin(3, Pin.OUT)
D6 = Pin(4, Pin.OUT)
D7 = Pin(5, Pin.OUT)
PORT = [2, 3, 4, 5]
L = [0,0,0,0]
def Configure():
for i in range(4):
L[i] = Pin(PORT[i], Pin.OUT)
def lcd_strobe():
EN.value(1)
utime.sleep_ms(1)
EN.value(0)
utime.sleep_ms(1)
def lcd_write(c, mode):
if mode == 0:
d = c
else:
d = ord(c)
d = d >> 4
for i in range(4):
b = d & 1
L[i].value(b)
d = d >> 1
RS.value(mode)
● 117
Raspberry Pi Pico for Radio Amateurs
lcd_strobe()
if mode == 0:
d = c
else:
d = ord(c)
for i in range(4):
b = d & 1
L[i].value(b)
d = d >> 1
RS.value(mode)
lcd_strobe()
utime.sleep_ms(1)
RS.value(1)
def lcd_clear():
lcd_write(0x01, 0)
utime.sleep_ms(5)
def lcd_home():
lcd_write(0x02, 0)
utime.sleep_ms(5)
def lcd_cursor_blink():
lcd_write(0x0D, 0)
utime.sleep_ms(1)
def lcd_cursor_on():
lcd_write(0x0E, 0)
utime.sleep_ms(1)
def lcd_cursor_off():
lcd_write(0x0C, 0)
utime.sleep_ms(1)
def lcd_puts(s):
l = len(s)
for i in range(l):
lcd_putch(s[i])
def lcd_putch(c):
lcd_write(c, 1)
def lcd_goto(col, row):
c = col + 1
if row == 0:
● 118
Chapter 5 • Simple Hardware-Based Projects
address = 0
if row == 1:
address = 0x40
address = address + c - 1
lcd_write(0x80 | address, 0)
def lcd_init():
Configure()
utime.sleep_ms(120)
for i in range(4):
L[i].value(0)
utime.sleep_ms(50)
L[0].value(1)
L[1].value(1)
lcd_strobe()
utime.sleep_ms(10)
lcd_strobe()
utime.sleep_ms(10)
lcd_strobe()
utime.sleep_ms(10)
L[0].value(0)
lcd_strobe()
utime.sleep_ms(5)
lcd_write(0x28, 0)
utime.sleep_ms(1)
lcd_write(0x08, 0)
utime.sleep_ms(1)
lcd_write(0x01, 0)
utime.sleep_ms(10)
lcd_write(0x06, 0)
utime.sleep_ms(5)
lcd_write(0x0C, 0)
utime.sleep_ms(10)
#================= END OF LCD FUNCTIONS =======================
Рис. 5.23: Программа: ЖК-дисплей.
Отображение текста
Следующее утверждение отображает текст «Hello from PICO» (эти утверждения должны
соответствовать функциям ЖК-дисплея, приведенным на рис. 5.23).
lcd_init()
lcd_puts('Hello from PICO')
● 119
Raspberry Pi Pico for Radio Amateurs
5.8 Проект 6: Счетчик секунд – параллельный ЖК-дисплейВ
этом проекте мы будем производить подсчет каждую секунду и отображать результат
на ЖК-дисплее. Цель проекта — показать, как можно отображать числовые данные на
ЖК-дисплее.
Программа называется LCDCount. Следующие операторы должны
соответствовать функциям LCD, приведенным на рис. 5.23.
lcd_init()
count = 0
while True:
lcd_goto(0, 0)
cntstr = str(count)
lcd_puts(cntstr)
count = count + 1
utime.sleep(1)
Сохранение функций ЖК-дисплея в библиотеке модулей.
Мы можем легко объединить все функции ЖК-дисплея в библиотеку, а затем импортировать
эту библиотеку в начало нашей программы. Шаги описаны ниже:
•
•
•
•
Откройте программу LCD (см. рис. 5.23)
В Thonny нажмите: File, затем Save As
Выберите Raspberry Pi Pico в качестве места назначения
Задайте имя файла LCD.py и нажмите ОК
Теперь вы можете импортировать библиотеку "LCD" в наши программы, работающие с
ЖК-дисплеями. Например, программу, представленную в этом проекте, можно написать так,
как показано на рис. 5.24 (Программа: LCDCount2). Обратите внимание, что перед всеми
функциями ЖК-дисплея должно стоять слово LCD.
#-------------------------------------------------------#
ЖК-дисплей, счетчик секунд
# ========================
#
# Эта программа ведет отсчет каждую секунду и отображает результаты на ЖК-дисплее.
#
# Author: Dogan Ibrahim
# File
: LCDCount2.py
# Date
: August, 2021
#---------------------------------------------------------import LCD
import utime
LCD.lcd_init()
● 120
Chapter 5 • Simple Hardware-Based Projects
count = 0
while True:
LCD.lcd_goto(0, 0)
cntstr = str(count)
LCD.lcd_puts(cntstr)
count = count + 1
utime.sleep(1)
Рис. 5.24: Программа LCDCount2.
5.9 Использование ЖК-дисплеев с интерфейсом I2C
В предыдущих разделах мы рассмотрели использование параллельных ЖК-дисплеев. Проблема
параллельных ЖК-дисплеев заключается в том, что для их управления требуется 6 контактов. В
отличие от них, I2C-ЖК-дисплей имеет 4 контакта: GND, +V, SDA и SCL. SDA подключен к
контакту SDA (контакт 4), а SCL — к контакту SCL (контакт 5) Raspberry Pi Pico соответственно.
Линия SCL — это тактовый сигнал, который всегда выводится ведущим устройством. Ведомое
устройство (в данном случае I2C-ЖК-дисплей) понижает напряжение на линии SDA только тогда,
когда подтверждает получение данных, и не отправляет никаких данных ведущему устройству.
Поэтому проблем с уровнем напряжения нет, если выходные контакты I2C Raspberry Pi Pico могут
управлять входами I2C-ЖК-дисплея, что и имеет место в данном случае.
На задней панели I2C-ЖК-дисплея установлена небольшая плата для управления интерфейсом
I2C. На большинстве модулей I2C LCD используется микросхема расширителя шины типа
PCF8574N для подключения LCD к внешнему миру через шину I2C. Контрастность LCD
регулируется с помощью небольшого потенциометра, установленного на этой плате. На плате
предусмотрена перемычка для отключения подсветки при необходимости.
Система I2C представляет собой многоведомую, многомастерную, одностороннюю
последовательную шину, используемую для подключения низкоскоростных периферийных
устройств к микроконтроллерам. Шина состоит всего из двух проводов, называемых SDA и SCL,
где SDA — линия данных, а SCL — линия тактового сигнала. На шине может поддерживаться до
1008 ведомых устройств. Обе линии должны быть подтянуты к напряжению питания
соответствующими резисторами. Тактовый сигнал всегда генерируется ведущим устройством
шины. Устройства на шине I2C могут обмениваться данными на частотах 100 кГц или 400 кГц.
5.10 Проект 7: Счетчик секунд с ЖК-дисплеем I2C
В этом проекте мы будем отсчитывать каждую секунду и отображать результат на ЖК-дисплее
I2C. Цель этого проекта — показать, как можно отображать числовые данные на ЖК-дисплее I2C.
Мы будем использовать ЖК-дисплей I2C в наших проектах в будущих разделах книги.
На рис. 5.25 показана принципиальная схема проекта.
● 121
Raspberry Pi Pico for Radio Amateurs
Рис. 5.25: Схема проекта.
Важное замечание. Некоторые устройства I2C, и в частности некоторые модули I2C LCD,
имеют встроенные подтягивающие резисторы на выводах SDA и SCL к напряжению питания.
Дисплеи I2C LCD обычно работают при напряжении +5 В, в то время как микросхема
PCF8574N на плате интерфейса I2C LCD может работать при напряжении не менее +3,3 В.
Питание ЖК-дисплея подключается к питанию микросхемы PCF8574N, поэтому для надежной
работы стандартных модулей I2C требуется напряжение +5 В. Проблема заключается в том,
что если I2C LCD имеет встроенные подтягивающие резисторы на линиях SDA и SCL, то мы
не можем напрямую подключать такие ЖК-дисплеи к выводам SDA и SCL Raspberry Pi Pico.
Это связано с тем, что выводы GPIO Raspberry Pi Pico не рассчитаны на напряжение +5 В и
могут быть легко повреждены при подаче напряжения +5 В.
Автор рекомендует один из следующих вариантов:
● 122
1.
Если используемый вами ЖК-дисплей с интерфейсом I2C не имеет встроенных
подтягивающих резисторов на выводах SDA и SCL, то можно безопасно
подключить эти выводы к выводам SDA и SCL Raspberry Pi Pico. При подключении
таких ЖК-модулей к Raspberry Pi Pico необходимо подключить подтягивающие
резисторы сопротивлением от 4,7 кОм до 10 кОм от выводов SDA и SCL к +3,3 В
Raspberry Pi Pico (возможно, внутренних подтягивающих резисторов Raspberry Pi
Pico будет достаточно, и внешние резисторы могут не потребоваться. Однако для
надежности рекомендуется использовать внешние подтягивающие резисторы). На
рисунке 5.25 и во всех других схемах на основе I2C в этой книге автор использовал
модуль ЖК-дисплея I2C без встроенных подтягивающих резисторов и подключил
выводы SDA и SCL к выводам SDA и SCL Raspberry Pi Pico с помощью
подтягивающих резисторов 10 кОм к +3,3 В.
2.
Если используемый вами ЖК-дисплей I2C имеет встроенные подтягивающие
резисторы на выводах SDA и SCL, то не подключайте такие модули ЖК-дисплея
напрямую к выводам Raspberry Pi Pico. Здесь есть два варианта: первый (если это
возможно) — найти и удалить два подтягивающих резистора с платы ЖК-дисплея
I2C. Второй вариант — использовать плату двунаправленного преобразователя
уровня напряжения I2C. В интернете доступно множество таких плат (например,
небольшая плата KY-051, включающая 4-битный двунаправленный
преобразователь уровня напряжения TXS0104). Необходимо подключить +5 В и
контакты SDA и SCL ЖК-модуля к верхней стороне платы преобразователя
Chapter 5 • Simple Hardware-Based Projects
уровней (например, к стороне b платы KY-051).Затем подключите +3,3 В и контакты
SDA и SCL платы Raspberry Pi Pico к нижней стороне платы преобразователя
уровней (например, к стороне a платы KY-051). Таким образом, напряжение на
контактах SDA и SCL платы Raspberry Pi Pico никогда не превысит рекомендуемое
значение +3,3 В (см. рис. 5.26 и 5.27).
Рис. 5.26: Использование модуля преобразования уровня напряжения.
Рис. 5.27: ЖК-дисплей и модуль преобразования уровня напряжения на макетной плате.
Перед использованием I2C LCD необходимо загрузить на Raspberry Pi Pico следующие два
файла библиотек Python (находятся в архиве). Самый простой способ загрузить их на Raspberry
Pi Pico — открыть их с помощью Thonny, а затем сохранить на Raspberry Pi Pico. Перед
сохранением необходимо ввести расширение файла .py:
lcd_api.py
pico_i2c_lcd.py
● 123
Raspberry Pi Pico for Radio Amateurs
К числу часто используемых функций, поддерживаемых библиотекой I2C, относятся:
очистить ЖК-экран
показать курсор
скрыть курсор
заставить курсор мигать
прекратить мигание курсора
переместить курсор в (x, y). x = 0 — первый столбец
записать символ в текущей позиции курсора
записать строку в текущей позиции курсора
clear()
show_cursor()
hide_cursor()
blink_cursor_on()
blink_cursor_off()
move_to(x, y)
putchar(char)
putstr(string)
На рис. 5.28 показан листинг демонстрационной программы под названием SecsCount.
В начале программы импортируются используемые в ней библиотеки. SDA и SCL
ЖК-дисплея подключены к выводам портов GP2 (вывод 4, SDA1) и GP3 (вывод 5, SCL1)
соответственно. ЖК-дисплей имеет 2 строки по 16 символов в каждой. I2C-адрес
ЖК-дисплея равен 0x27.
Остальная часть программы выполняется в цикле, где переменная count увеличивается,
преобразуется в строку и затем отображается на ЖК-дисплее.
#=============================================================
#
Счетчик секунд на ЖК-дисплее I2C
#
# Эта программа использует ЖК-дисплей с интерфейсом I2C и отображает секунды на экране.
#
# Author: DOgan Ibrahim
# Date
: August, 2021
# File
: SecsCount.py
#==============================================================
from machine import I2C, Pin
from pico_i2c_lcd import I2cLcd
import utime
i2c_lcd = I2C(id=1,scl=Pin(3),sda=Pin(2),freq=100000)
lcd = I2cLcd(i2c_lcd, 0x27, 2, 16)
count = 0
while True:
lcd.move_to(0, 0)
cntrstr = str(count)
lcd.putstr(cntrstr)
count = count + 1
utime.sleep(1)
Рис. 5.28: Листинг программы.
● 124
Chapter 6 • Amateur Radio Hardware-based Projects
Глава 6 • Аппаратные проекты для любительской радиосвязи
6.1 Обзор
В этой главе мы будем разрабатывать аппаратные проекты для любительской радиосвязи с
использованием Raspberry Pi Pico и текстового редактора Thonny. Для этих проектов
предполагается, что Raspberry Pi Pico подключен к USB-порту ПК. См. важные примечания в
разделе 5.10 об использовании ЖК-дисплеев, совместимых с I2C, в проектах. Эти примечания
также относятся к некоторым проектам, описанным в этой главе.
Проект 1: Управление питанием станции от сети
В этом проекте к Raspberry Pi Pico подключены 4 кнопки и 4 реле. Реле меняют состояние при
нажатии соответствующих кнопок. Например, к сети переменного тока через реле можно
подключить различное оборудование, работающее от сети, и легко включать или выключать
его нажатием соответствующей кнопки. Цель этого проекта — показать, как можно
подключить кнопки и реле к Raspberry Pi Pico, а также как такая схема может использоваться
радиолюбителями для легкого включения и выключения своего оборудования.
На рис. 6.1 показана блок-схема проекта.
Рис. 6.1: Блок-схема проекта.
В этом проекте используется 4-канальная релейная плата (см. рис. 6.2) от компании Elegoo
(www.elegoo.com). Это плата с оптоэлектронной связью, имеющая 4 входа, по одному для
каждого канала. Входы реле расположены в правом нижнем углу платы, а выходы — в
верхнем. Среднее положение каждого реле является общей точкой; соединение слева от него
— это нормально замкнутый (NC) контакт, а соединение справа — нормально разомкнутый
(NO) контакт. Контакты реле поддерживают напряжение 250 В переменного тока при токе 10 А
и 30 В постоянного тока при токе 10 А. IN1, IN2, IN3 и IN4 — это активные входы с низким
уровнем сигнала, что означает, что реле активируется при подаче логического сигнала
низкого уровня на его входной контакт. Контакты реле являются нормально замкнутыми (NC).
Активация реле изменяет активные контакты таким образом, что общий контакт и контакт NC
становятся двумя контактами реле. Одновременно загорается светодиод на входной цепи
платы реле, соответствующий активированному реле. Линия питания VCC может быть
подключена либо к +3,3 В, либо к +5 В. Перемычка JD используется для выбора напряжения
для реле.
Поскольку ток, потребляемый реле, может превышать 80 мА, необходимо снять эту
перемычку и подключить внешний источник питания (например, +5 В) к выводу JD-VCC.
● 125
Raspberry Pi Pico for Radio Amateurs
Рис. 6.2: 4-канальная релейная плата.
Схема подключения проекта показана на рис. 6.3. Кнопки обозначены буквами A, B, C и D и
подключены к контактам GP0, GP1, GP2 и GP3 портов Raspberry Pi соответственно. Выходы
кнопок имеют логическое значение 1 и переходят в логическое значение 0 при нажатии
соответствующей кнопки. Контакты IN1, IN2, IN3 и IN4 модуля реле подключены к контактам
GP16, GP17, GP18 и GP19 портов соответственно. Контакты реле должны быть подключены к
оборудованию, которое необходимо включить/выключить, через сеть переменного тока.
ВНИМАНИЕ. Следует соблюдать осторожность при работе с напряжением сети и обратиться
за профессиональной помощью, если вы не уверены в правильности подключения к сети.
Рис. 6.3: Схема цепи проекта.
● 126
Chapter 6 • Amateur Radio Hardware-based Projects
На рис. 6.4 показан листинг программы (program:relays.py). В начале программы
определяются соединения кнопок и реле с Raspberry Pi Pico. Контакты портов, к которым
подключены входные контакты реле IN1-IN4, настраиваются как выходы. Контакты портов, к
которым подключены контакты кнопок BUTTONA, BUTTONB, BUTTONC и BUTTOND,
настраиваются как входы, и эти контакты внутренне подтягиваются к высокому уровню
Raspberry Pi Pico. Затем все 4 реле выключаются в начале программы. Остальная часть
программы выполняется внутри основного цикла программы, где используется цикл while.
Здесь функция TestButton используется для проверки состояния кнопки, и если кнопка
нажата,то состояние соответствующего реле изменяется.
Функции — это полезные инструменты программирования, которые используются, когда
части программы должны повторяться несколько раз. Объявление функции в Python
начинается с ключевого слова `def`, за которым следует квадратная скобка. Внутри
скобкиуказываются аргументы, которые будут переданы функции (если таковые
имеются). Обратите внимание, что аргументы являются локальными для функции. Здесь
показана функция `FunctionTestButton`:
def TestButton(Button, IN):
if Button.value() == 0:
s = IN.value()
if s == ON:
IN.value(OFF)
else:
IN.value(ON)
while Button.value() == 0:
pass
Вторая строка функции проверяет, равно ли значение кнопки 0, то есть нажата ли кнопка.
Помните, что обычно, когда кнопка не нажата, её состояние — логическая единица. Если
кнопка нажата, считывается состояние соответствующего вывода реле. Если реле включено,
то оно переводится в выключенное состояние путем отправки сигнала OFF на
соответствующий вывод IN. Если же реле выключено, то на соответствующий вывод IN
отправляется сигнал ON, который включает его. Затем функция ожидает, пока кнопка не будет
отпущена.
#--------------------------------------------------------------#
УПРАВЛЕНИЕ ВКЛЮЧЕНИЕМ/ВЫКЛЮЧЕНИЕМ СЕТИ СТАНЦИИ
#
----------------------------------------------------# В этом проекте к Raspberry Pi Pi подключены 4 кнопки и 4 реле.
# Состояние реле меняется каждый раз, когда нажимается
# соответствующая кнопка. Таким образом, если реле включено,
# оно выключается, если выключено, оно включается и т. д.
#
# Author: Dogan Ibrahim
# File
: relays.py
# Date
: August, 2021
#--------------------------------------------------------------from machine import Pin
● 127
Raspberry Pi Pico for Radio Amateurs
import utime
#
# Кнопочные соединения
#
BUTTONA = Pin(0, Pin.IN, pull=Pin.PULL_UP)
# Button A
BUTTONB = Pin(1, Pin.IN, pull=Pin.PULL_UP)
# Button B
BUTTONC = Pin(2, Pin.IN, pull=Pin.PULL_UP)
# Button C
BUTTOND = Pin(3, Pin.IN, pull=Pin.PULL_UP)
# Button D
OFF = 1
ON = 0
#
# Контакты управления реле
#
IN1 = Pin(16, Pin.OUT)
# IN1 pin
IN2 = Pin(17, Pin.OUT)
# IN2 pin
IN3 = Pin(18, Pin.OUT)
# IN3 pin
IN4 = Pin(19, Pin.OUT)
# IN4 pin
#
# В начале выключите все реле.
#
IN1.value(OFF) # IN1 OFF
IN2.value(OFF) # IN2 OFF
IN3.value(OFF) # IN3 OFF
IN4.value(OFF) # IN4 OFF
#
# Эта функция проверяет, нажата ли кнопка, и переключает контакт IN
# реле. Если реле включено, оно выключается; если выключено,
# оно включается.
#
def TestButton(Button, IN):
if Button.value() == 0:
s = IN.value()
if s == ON:
IN.value(OFF)
else:
IN.value(ON)
while Button.value() == 0:
pass
#
# Вызовите функцию TestButton для активации/деактивации реле.
#
● 128
Chapter 6 • Amateur Radio Hardware-based Projects
while True: # Делать вечно
TestButton(BUTTONA, IN1)
# Проверка кнопки А
TestButton(BUTTONB, IN2)
# Test Button B
TestButton(BUTTONC, IN3)
# Test Button C
TestButton(BUTTOND, IN4)
# Test Button D
utime.sleep(0.1)
Рис. 6.4: Программа: relays.py.
На рис. 6.5 показана схема, собранная на макетной плате. Для подачи внешнего напряжения
на релейный модуль использовался внешний источник питания +5 В.
Рис. 6.5: Проект, собранный на макетной плате.
6.3 Проект 2: Станционные часы
В этом проекте мы разработаем ЖК-часы для отображения текущей даты и времени каждую
секунду на двухстрочном ЖК-дисплее на базе I2C. Цель проекта — показать, как модуль часов
реального времени (RTC) может использоваться для хранения даты и времени, а также как
эти данные могут считываться и отображаться на ЖК-дисплее.
На рис. 6.6 показана блок-схема проекта. В этом проекте используется модуль на базе
микросхемы RTC DS1307 (рис. 6.7). Этот модуль подключается к внешнему миру через шину
I2C. Этот модуль обладает следующими характеристиками:
• подсчет секунд, минут, часов, месяца, дня, года, дня недели
и компенсация високосного года
•
•
•
•
56-байтовая оперативная память общего назначения с резервным питанием от батареи
программируемый выходной сигнал в виде прямоугольного сигнала
потребление тока менее 500 нА
широкий температурный диапазон
● 129
Raspberry Pi Pico for Radio Amateurs
Рис. 6.6: Блок-схема проекта.
Рис. 6.7: Модуль RTC DS1307.
Схема подключения показана на рис. 6.8. Контакты SDA и SCL I2C LCD подключены к
контактам SDA1 (контакт 4) и SCL1 (контакт 5) Raspberry Pi Pico. Аналогично, контакты SDA и
SCL модуля RTC DS1307 подключены к контактам SDA0 (контакт 1) и SCL0 (контакт 2)
Raspberry Pi Pico. Кроме того, контакты заземления и VCC обоих модулей подключены к
контактам GND и +5V Raspberry Pi Pico.
● 130
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.8: Схема проекта.
Имеется две программы: одна для первоначальной установки даты и времени (setdatetime.py), а
другая для чтения даты и времени по мере необходимости (getdatetime.py). На рис. 6.9 показан
листинг программы setdatetime.py. Здесь в программу импортируется библиотека DS1307
ds1307.py (находится в архиве). Пользователю предлагается ввести текущую дату и время. Эти
данные сохраняются в DS1307 и автоматически обновляются, даже если Raspberry Pi Pico
выключен.
#============================================================
#
УСТАНОВИТЕ ТЕКУЩУЮ ДАТУ И ВРЕМЯ
#
# Эта программа устанавливает текущую дату и время, которые
# сохраняются и обновляются автоматически, поскольку
# модуль RTC включает батарею
#
# Author: Dogan Ibrahim
# Date
: August 2021
# File
: setdatetime.py
#============================================================
from ds1307 import DS1307
from machine import I2C, Pin
#
# Модуль RTC подключен к SDA0, SCL0
#
i2c_rtc = I2C(0,scl = Pin(1),sda = Pin(0),freq = 100000)
RTC = DS1307(i2c_rtc)
● 131
Raspberry Pi Pico for Radio Amateurs
print("Enter the current date and time")
year = int(input("Year: "))
month = int(input("Month (Jan = 1 ): "))
date = int(input("Date: "))
day = int(input("Day (monday = 1 ): "))
hour = int(input("Hour (24 Hour format): "))
minute = int(input("Minute: "))
second = int(input("Second: "))
now = (year,month,date,day,hour,minute,second,0)
RTC.datetime(now)
print("Date and time are set to:")
print(RTC.datetime())
Рис. 6.9: Программа: setdatetime.py.
На рис. 6.10 показан листинг программы getdatetime.py. Эта программа запускается всякий
раз, когда необходимо отобразить текущую дату и время. Здесь I2C LCD-дисплей назначен на
порт I2C 1, а модуль RTC — на модуль I2C 0. Программа считывает текущую дату и время и
отображает их в формате, показанном на рис. 6.11.
#============================================================
#
ОТОБРАЖЕНИЕ ТЕКУЩЕЙ ДАТЫ И ВРЕМЕНИ
#
# Эта программа считывает текущую дату и время с модуля RTC
# типа DS1307 и отображает их на ЖК-дисплее с интерфейсом I2C.
#
# Author: Dogan Ibrahim
# Date
: August 2021
# File
: getdatetime.py
#============================================================
from machine import I2C, Pin
from ds1307 import DS1307
from pico_i2c_lcd import I2cLcd
import utime
#
# Модуль RTC подключен к SDA0, SCL0
#
i2c_rtc = I2C(0,scl = Pin(1),sda = Pin(0),freq = 100000)
#
# Модуль ЖК-дисплея с интерфейсом I2C подключен к контактам SDA1 и SCL1.
#
i2c_lcd = I2C(id=1,scl=Pin(3),sda=Pin(2),freq=100000)
lcd = I2cLcd(i2c_lcd, 0x27, 2, 16)
● 132
Chapter 6 • Amateur Radio Hardware-based Projects
RTC = DS1307(i2c_rtc)
while True:
(year,month,date,day,hours,minutes,seconds,x) = RTC.datetime()
lcd.move_to(0,0)
lcd.putstr("Date:")
lcd.move_to(5, 0)
dt = str(date)
if date < 10:
dt = "0" + dt
mon = str(month)
if month < 10:
mon = "0" + mon
CurrentDate = dt + "/" + mon + "/" + str(year)
lcd.putstr(CurrentDate)
lcd.move_to(0, 1)
lcd.putstr("Time:")
lcd.move_to(5,1)
hrs = str(hours)
if hours < 10:
hrs = "0" + hrs
mins = str(minutes)
if minutes < 10:
mins = "0" + mins
secs = str(seconds)
if seconds < 10:
secs = "0" + secs
CurrentTime = hrs + ":" + mins + ":" + secs
lcd.putstr(CurrentTime)
utime.sleep(1)
Рис. 6.10: Программа: getdatetime.py.
Рис. 6.11: Пример отображения текущей даты и времени.
● 133
Raspberry Pi Pico for Radio Amateurs
6.4 Проект 3: Температура и влажность на станции
В некоторых случаях нам может потребоваться узнать температуру и влажность окружающей
среды в нашей радиостанции («радиостанции») перед началом связи по воздуху. Этот проект
демонстрирует, как считывать показания температуры и влажности окружающей среды с
датчика и отображать эти значения на ЖК-дисплее. В этом проекте мы будем считывать
показания температуры и влажности окружающей среды и отображать их на ЖК-дисплее
каждые 5 секунд.
На рис. 6.12 показана блок-схема проекта. В этом проекте используется микросхема
датчика температуры и влажности типа DHT11.
Рис. 6.12: Блок-схема проекта.
Микросхема датчика температуры и влажности DHT11 обычно представляет собой
3-контактный датчик (существует также 4-контактная версия этого датчика, где один из
контактов не используется) с контактами GND, +V и Data. GND и +V подключены к линии
заземления и контактам питания +3,3 В Raspberry Pi. Контакт Data должен быть подключен к
+V через резистор 10 кОм. В этом проекте используется 3-контактный датчик DHT11 от Elektor
со встроенным подтягивающим резистором 10 кОм. Как показано на рис. 6.13, контакт Data
датчика обозначен как «S», и он подключен к контакту GPIO Pico Raspberry Pi.
Рис. 6.13: Датчик DHT11.
● 134
Chapter 6 • Amateur Radio Hardware-based Projects
Датчик DHT11 использует емкостной датчик влажности и терморезистор для измерения
температуры окружающей среды. Данные с микросхемы поступают примерно каждую секунду.
Основные характеристики DHT11:
•
•
•
•
•
работа от 3 В до 5 В
потребление тока 2,5 мА (во время преобразования)
измерение температуры в диапазоне 0–50ºC с точностью ±2ºC
измерение влажности в диапазоне 20–80% с точностью 5%
совместимость с макетной платой с шагом выводов 0,1 дюйма
На рис. 6.14 показана принципиальная схема проекта. Вывод данных DHT11 подключен к
выводу порта GP0 (вывод 1) Raspberry Pi Pico.
Рис. 6.14: Схема цепи проекта.
В этой программе используется библиотека DHT11 dht11.py (находится в архиве). Этот файл
необходимо скопировать на Raspberry Pi Pico с помощью Thonny. Перед копированием
убедитесь, что имя файла содержит расширение .py.
На рис. 6.15 показан листинг программы (program:TempHum.py). В начале программы
импортируются используемые библиотеки. Затем настраивается ЖК-дисплей I2C с адресом
0x27. Остальная часть программы выполняется в цикле while. Внутри этого цикла
температура и влажность окружающей среды считываются с микросхемы датчика,
преобразуются в строки, а затем отображаются на дисплее в формате, показанном
на рис. 6.16.
#============================================================
#
ОТОБРАЖЕНИЕ ТЕМПЕРАТУРЫ И ВЛАЖНОСТИ
#
# Эта программа считывает температуру и влажность окружающей среды
# с микросхемы датчика DHT11 и затем отображает их на ЖК-дисплее с интерфейсом I2C.
● 135
Raspberry Pi Pico for Radio Amateurs
#
# Author: Dogan Ibrahim
# Date
: August 2021
# File
: TempHum.py
#============================================================
from dht11 import *
from machine import I2C, Pin
from pico_i2c_lcd import I2cLcd
import utime
#
# Модуль ЖК-дисплея с интерфейсом I2C подключен к контактам SDA1 и SCL1.
#
i2c_lcd = I2C(id=1,scl=Pin(3),sda=Pin(2),freq=100000)
lcd = I2cLcd(i2c_lcd, 0x27, 2, 16)
lcd.putstr("Temp + Humidity")
utime.sleep(2)
lcd.clear()
MyDHT = DHT(0)
#
# Считывать и отображать температуру и влажность.
#
while True:
temperature,humidity=MyDHT.readTempHumid()
tempstr = str(temperature)[:5]
humstr = str(humidity)[:5]
lcd.move_to(0, 0)
lcd.putstr("T(C): ")
lcd.move_to(6, 0)
lcd.putstr(tempstr)
lcd.move_to(0, 1)
lcd.putstr("H(%): ")
lcd.move_to(6, 1)
lcd.putstr(humstr)
utime.sleep(5)
Рис. 6.15: Листинг программы.
● 136
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.16: Пример отображения температуры и влажности.
6.5 Проект 4: Географические координаты станции
В некоторых случаях, особенно при работе в мобильном режиме, может потребоваться узнать
текущие географические координаты (например, широту и долготу). В этом проекте мы будем
использовать GPS для считывания и отображения географических координат нашей станции на
ЖК-дисплее.
GPS-устройства получают географические данные от специализированных GPS-спутников и
предоставляют точную информацию о местоположении пользователя на Земле. Эти спутники
вращаются вокруг Земли на высоте около 20 000 км и совершают два полных оборота в день.
Для определения своего местоположения приемнику необходимо поддерживать связь (или
«видеть») как минимум с тремя спутниками. Поэтому, если у приемника нет беспрепятственного
обзора неба, определить его местоположение на Земле может быть невозможно. В некоторых
приложениях внешние антенны позволяют принимать даже слабые сигналы от GPS-спутников.
Данные, выдаваемые GPS-приемником, имеют текстовый формат и известны как
«NMEA-сообщения». Каждое NMEA-сообщение начинается с символа $, а значения в
сообщении разделяются запятыми. Ниже приведены некоторые NMEA-сообщения,
возвращаемые GPS-приемником:
$GPGLL: Это предложение содержит локальные географические широту и
долготу, скорость, угол траектории, дату, время и магнитное склонение.
$GPRMC: Это предложение содержит локальные географические широту и
долготу, скорость, угол траектории, дату, время и магнитное склонение.
$GPVTG: Это предложение содержит истинную траекторию, магнитную траекторию
и скорость относительно земли.
$GGGA: Это предложение содержит локальные географические широту и долготу,
время, качество определения местоположения, количество отслеживаемых
спутников, горизонтальное ослабление координат, высоту, высоту геоида
и данные DGPS.
● 137
Raspberry Pi Pico for Radio Amateurs
$GPGSV: Здесь 4 предложения с этим заголовком. Эти предложения содержат
количество видимых спутников, номер спутника, угол места, азимут и отношение
сигнал/шум.
В этом проекте используется плата GPS Click от Mikro Elektronika (www.mikroe.com). Это
небольшой GPS-приемник (см. рис. 6.17), основанный на GPS-модуле LEA-6S. Эта плата
работает при напряжении +3,3 В и обеспечивает два типа выходов: I2C или
последовательный вывод. В этом проекте используется последовательный вывод по
умолчанию, работающий со скоростью 9600 бод. К плате можно подключить внешнюю
динамическую антенну для улучшения приема при использовании внутри помещений или в
местах с плохим обзором неба.
Рис. 6.17: Плата GPS Click.
На рис. 6.18 показан полный список NMEA-сообщений, выводимых платой GPS Click каждую
секунду.
Рис. 6.18: Выходные NMEA-сообщения с платы GPS Click.
Плата GPS Click представляет собой двухрядный (DIL) модуль с 2×8 контактами и
имеет следующую конфигурацию выводов (контакт 1 — верхний левый контакт
модуля):
1:
2:
3:
4:
5:
6:
7:
8:
● 138
No connection
Reset
No connection
No connection
No connection
No connection
+3.3V
GND
16: No connection
15: No connection
14: TX
13: RX
12: SCL
11: SDA
10: No connection
9: GND
Chapter 6 • Amateur Radio Hardware-based Projects
При последовательной работе требуются только следующие контакты: +3,3 В, GND, TX. В
этом проекте к плате GPS Click подключена внешняя динамическая антенна, поскольку она
использовалась в помещении.
$GPGLL — это одно из часто используемых предложений NMEA, и именно оно используется в
этом проекте для извлечения географических координат станции. Вывод этого предложения
осуществляется в следующем формате:
$GPGLL,5127.37032,N,00003.12782,E,221918.00,A,A*61
Поля в этом предложении можно расшифровать следующим образом:
GLL
5127.37032
00003.12782
221918
A
*61
Географическое положение, широта и долгота
Широта 51°, 27,3702 мин. северной широты
Longitude 0 deg, 3.12782 min. East
Исправление внесено в 22:19:18 UTC.
Данные активны (или V означает пустоту)
контрольная сумма данных
Обратите внимание, что поля разделены запятыми. Достоверность данных обозначается
буквами A или V, где A означает, что данные действительны, а V — что данные
недействительны.
На рис. 6.19 показана блок-схема проекта. Для отображения положения и долготы
GPS-приемника пользователя используется ЖК-дисплей с интерфейсом I2C.
Рис. 6.19: Блок-схема проекта.
● 139
Raspberry Pi Pico for Radio Amateurs
Raspberry Pi Pico взаимодействует с модулем GPS по последовательному каналу связи.
Raspberry Pi Pico имеет два последовательных порта, как показано на рис. 6.20. Они
обозначены как UART0 и UART1, оба имеют контакты TX и RX, как показано на рисунке.
Обратите внимание, что несколько портов используют UART0 и UART1 совместно, и
одновременно может использоваться только один из каждого совместно используемого порта.
Рис. 6.20: Последовательные порты UART Raspberry Pi Pico.
Схема проекта показана на рис. 6.21. Контакт UART TX платы GPSclick (контакт 14)
подключен к входу RXD (GP1) Raspberry Pi Pico. I2CLCD подключен так же, как и в
предыдущих проектах, т.е. контакты SDA и SCL подключены к GPI2 и GP3 соответственно.
Плата GPSclick питается от источника питания +3,3 В Raspberry Pi.
Рис. 6.21: Схема проекта.
● 140
Chapter 6 • Amateur Radio Hardware-based Projects
В этом проекте широта и долгота извлекаются из NMEA-сообщения $GPGLL без
использования библиотек. На рис. 6.22 показан листинг программы (program:gps.py). В
начале программы импортируются следующие библиотеки:
Функция Get_GPS() принимает строку NMEA-сообщения и ищет строку $GPGLL. При
обнаружении этой строки строка разбивается на части, разделённые запятыми, с помощью
встроенной функции split(",") и сохраняется в переменной sdata. Если 6-е поле содержит
символ V, предполагается, что сообщение недействительно (например, отсутствует
спутниковый приём), и в верхней строке ЖК-дисплея отображается текст NO DATA. В
противном случае широта и её направление извлекаются из полей 1 и 2 и сохраняются в
переменных lat и latdir соответственно. Долгота и её направление извлекаются из полей 3
и4 и сохраняются в переменных lon и londir соответственно.
Широта принимается в формате: ddmm.mmmmmD, что соответствует dd градусам
мм.mmmmm минутам, а направление D — север или юг. Аналогично, долгота принимается
в формате: dddmm.mmmmmD, где D — восток или запад. Основная программа разделяет
градусы и минуты и отображает их на ЖК-дисплее. Широта отображается в верхней строке
ЖК-дисплея в формате: ddmm.mmmmmD, а долгота — в формате: dddmm.mmmmmD.
#--------------------------------------------------------------#
ГЕОГРАФИЧЕСКИЕ КООРДИНАТЫ СТАНЦИИ
#
-------------------------------------
#
# В этом проекте модуль GPS-приемника (GPS CLICK) подключен
# к последовательному входу (GP1) Raspberry Pi Pico. Дополнительно подключен
# ЖК-дисплей с интерфейсом I2C. Программа отображает широту и
# долготу местоположения приемника на ЖК-дисплее.
#
# Author: Dogan Ibrahim
# File
: gps.py
# Date
: August, 2021
#--------------------------------------------------------------from machine import I2C, Pin
from pico_i2c_lcd import I2cLcd
from machine import UART
import utime
#
# Модуль ЖК-дисплея с интерфейсом I2C подключен к контактам SDA1 и SCL1.
#
i2c_lcd = I2C(id=1,scl=Pin(3),sda=Pin(2),freq=100000)
lcd = I2cLcd(i2c_lcd, 0x27, 2, 16)
#
# Настройка UART для скорости 9600 бод
● 141
Raspberry Pi Pico for Radio Amateurs
#
uart = UART(0, 9600)
lat=latdir=lon=londir = "0"
flag=0
#
# Эта функция получает и извлекает широту и долготу
# из NMEA-сообщения $PGLL.
#
def Get_GPS(data):
global lat,latdir,lon,londir,flag
if data:
dat = data.decode('UTF-8')
if dat[0:6] == "$GPGLL":
sdata = dat.split(",")
# Разделение данных
if len(sdata) >= 7:
if sdata[6] == "V":
# Достоверные данные?
lcd.clear()
# Очистить ЖК-дисплей
lcd.move_to(0, 0)
# В точке 0,0
lcd.putstr("NO DATA")
# Нет данных
return
lat = sdata[1]
# Получить широту
latdir = sdata[2]
# Направление широты
lon = sdata[3]
# Получить долготу
londir = sdata[4]
# Направление долготы
flag=1
return
else:
lcd.clear()
lcd.putstr("wait...")
utime.sleep(1)
while flag == 0:
data = uart.readline()
Get_GPS(data)
# Расшифровка
flag=1
deg = lat[0:2]
min = lat[2:]
latitude = str(deg) + " " + str(min) + "
" + str(latdir)
deg = lon[0:3]
min = lon[3:]
longitude = str(deg) + " " + str(min) + " " + str(londir)
● 142
Chapter 6 • Amateur Radio Hardware-based Projects
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr(latitude)
# Дисплейная широта
lcd.move_to(0, 1)
lcd.putstr(longitude)
# Отобразить долготу
Рис. 6.22: Программа: gps.py.
.
Пример отображения информации на ЖК-дисплее показан на рис. 6.23.
Рис. 6.23: Пример отображения на ЖК-дисплее.
Использование второго ЖК-дисплея с интерфейсом I2C
В этом и предыдущих проектах с использованием I2C LCD адрес устройства I2C по умолчанию
установлен на 0x27. В проекте можно использовать более одного LCD, если у них разные
адреса I2C. Адрес LCD можно установить, припаяв перемычки к 6 контактам, обозначенным как
A0, A1 и A2, на обратной стороне LCD, как показано на рисунке 6.24:
Рис. 6.24: Перемычки адреса I2C ЖК-дисплея.
● 143
Raspberry Pi Pico for Radio Amateurs
Выбор адреса осуществляется следующим образом, где 1 соответствует перемычке,
припаянной между двумя указанными контактными площадками:
A2
Номер
0
0
0
1
1
1
1
A1
A0
перемычки
0
1
1
0
1
1
0
0
0
1
1
0
1
1
Address
0x27 (по умолчанию)
0x26
0x25
0x24
0x23
0x22
0x21
0x20
6.6 Генерация сигналов – с помощью программного обеспечения
Генераторы сигналов являются важными инструментами для радиолюбителей. Существует
множество коммерчески доступного оборудования для генерации различных сигналов. В этом
разделе мы будем разрабатывать проекты по генерации различных аналоговых сигналов,
таких как прямоугольные, синусоидальные, треугольные, ступенчатые и т. д., путем
программирования Raspberry Pi Pico.
Перед генерацией аналогового сигнала необходимо использовать микросхему
цифро-аналогового преобразователя (ЦАП) для преобразования сгенерированных цифровых
сигналов в аналоговую форму. Raspberry Pi Pico не имеет встроенного ЦАП, поэтому для
вывода аналоговых сигналов требуется использовать внешнюю микросхему ЦАП. В этой книге
мы будем использовать популярную микросхему ЦАП MCP4921 от Microchip.
ЦАП используются для преобразования цифровых сигналов в аналоговую форму. Такие
преобразователи имеют множество применений в цифровой обработке сигналов и цифровых
системах управления. Например, мы можем генерировать сигналы, написав программы, а
затем преобразовывать эти сигналы в аналоговые формы и выводить их с нашего цифрового
компьютера. Нам также понадобятся ЦАП, если мы хотим подключить динамик или другое
устройство, работающее с аналоговыми напряжениями, к нашему Raspberry Pi Pico.
ЦАП MCP4921
Перед использованием MCP4921 стоит подробно ознакомиться с его характеристиками и
принципами работы. MCP4921 — это 12-битный ЦАП, работающий с интерфейсом шины SPI.
На рисунке 6.25 показана схема расположения выводов этого чипа. Основные характеристики
(12-битная работа):
•
•
•
•
•
•
•
● 144
Поддержка тактовой частоты 20 МГц
Время установления 4,5 мкс
Вход внешнего опорного напряжения
Регулировка усиления до единицы или 2x
Усиление 1x или 2x
Напряжение питания от 2,7 до 5,5 В
Диапазон температур от -40ºC до +125ºC
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.25: ЦАП Microchip MCP4921
Описание выводов:
Vdd:
CS:
SCK:
SDI:
LDAC:
Vref
Vout:
Vss:
Напряжение питания
выбор микросхемы (активный низкий уровень)
тактовый сигнал SPI
вход данных SPI
Используется для передачи данных входного регистра на выход
(активный низкий уровень) Опорное входное напряжение
аналоговый выход
земля питания
В этом проекте мы будем использовать MCP4921 с коэффициентом усиления 1. В результате,
при опорном напряжении 3,3 В и 12-битных данных преобразования, разрешение младшего
значащего бита ЦАП составит 3300 мВ / 4096 = 0,8 мВ.
6.6.1 Проект 5: Генерация прямоугольного сигнала с амплитудой менее +3,3 В
В этом проекте мы будем использовать ЦАП для генерации прямоугольного сигнала с
частотой 500 Гц (период = 2 мс) и коэффициентом заполнения 50% (т.е. время включения = 1
мс, время выключения = 1 мс). Выходное напряжение составит 2 В пикового значения
(обратите внимание, что этого нельзя было бы достичь без использования ЦАП, поскольку
выходное напряжение высокого уровня на выводе составляет +3,3 В).
На рис. 6.26 показана блок-схема проекта.
Рис. 6.26 блок-схема проекта.
● 145
Raspberry Pi Pico for Radio Amateurs
Схема проекта показана на рис. 6.27. Выводы GP3 (SPI0 TX) и GP2 (SPIOSCK) подключены к
выводам SDI и SCK микросхемы MCP4921 соответственно. Управление CS микросхемы
MCP4921 осуществляется отдельно от вывода GP16 (вывод 21). Выход ЦАП подключен к
осциллографу.
Рис. 6.27: Схема проекта.
Данные записываются в ЦАП двумя байтами. Младший байт определяет D0:D8 цифровых
входных данных. Старший байт состоит из следующих битов:
D8:D11
Биты D8:D11 цифровых входных данных:
SHDN
1: активен (выход доступен), 0: выключение устройства
Регулировка выходного усиления. 0: усиление в 2 раза, 1:
GA
усиление в 1 раз.
BUF 0: вход без буферизации, 1: вход с буферизацией
0: запись в DACa, 1: запись в DACb (MCP4921 поддерживает
A/B
только DACa)
В обычном режиме работы вы отправляете старший байт (D8:D11) 12-битных (D0:D11)
входных данных, при этом биты D12 и D13 установлены в 1, чтобы устройство было активным,
а коэффициент усиления установлен на 1x. Затем вы отправляете младший байт (D0:D7)
данных. Это означает, что к старшему байту следует добавить 0x30 перед отправкой на ЦАП.
На рис. 6.28 показан листинг программы (программа: Square). Поскольку мы используем ЦАП
с опорным напряжением +3,3 В (3300 мВ) и 12-битными данными (т.е. 4096 шагов), требуемое
цифровое значение для установки выходного напряжения на 2 В определяется как ONvalue,
где:
ONvalue = 2000 × 4095 / 3300
Значение OFF сигнала (OFFvalue) устанавливается на 0 В. Функция DAC настраивает ЦАП
таким образом, чтобы на его выходе было 2 В. Сначала старший байт (в буфере [0])
помещается в буфер, затем младший байт (в буфере [1]):
● 146
Chapter 6 • Amateur Radio Hardware-based Projects
buff[0] = (data >> 8) & 0x0F
buff[0] = buff[0] + 0x30
buff[1] = data & 0xFF
spi.write(bytearray(buff))
Длительность включения и выключения установлена на 1 мс. Однако в ходе экспериментов
было обнаружено, что обработка сигнала ЦАП занимает некоторое время, и поэтому период, а
следовательно, и частота выходного сигнала не являются идеально точными. Время
включения и выключения немного больше 1 мс. При необходимости читатели могут
поэкспериментировать, чтобы отрегулировать задержку и получить точно 1 мс.
#---------------------------------------------------------#
СГЕНЕРИРОВАТЬ ПРЯМОУГОЛЬНЫЙ СИГНАЛ С АМПЛИТУДОЙ 2В
======================================================
#
# В этом проекте микросхема ЦАП типа MCP4921 подключена к
# Raspberry Pi Pico. Программа генерирует прямоугольный сигнал
# с частотой f=500 Гц, коэффициентом заполнения 50% (время
# включения и выключения равно и составляет 1 мс), амплитудой 2 В.
#
# Author: Dogan Ibrahim
# File
: Square.py
# Date
: August 2021
#-----------------------------------------------------------from machine import Pin, SPI
import utime
spi_sck = Pin(2)
# Контакт SCK на GP2
spi_tx = Pin(3)
# Контакт TX на GP3
spi_rx = Pin(0)
# Контакт RX на GP0 (не используется)
spi = SPI(0,sck=spi_sck,mosi=spi_tx,miso=spi_rx,baudrate=100000)
CS = Pin(16, Pin.OUT)
# CS
CS.value(1) # Отключить чип
ONvalue = int(2000 * 4095 / 3300)
# Для амплитуды +2 В
OFFvalue = 0
def DAC(data):
buff = [0, 0]
buff[0] = (data >> 8) & 0x0F
# Старший байт
buff[0] = buff[0] + 0x30
buff[1] = data & 0xFF
# Младший байт
CS.value(0)
# Включить MCP4921
spi.write(bytearray(buff)) # Send to SPI bus
● 147
Raspberry Pi Pico for Radio Amateurs
CS.value(1)
# Отключить MCP4921
#
# Основная программа
#
while True:
DAC(ONvalue)
utime.sleep_ms(1000)
DAC(OFFvalue)
utime.sleep_ms(1000)
Рис. 6.28: Программа: Square.
.
На рис. 6.29 показана выходная осциллограмма, сгенерированная программой. Эта
осциллограмма была получена с помощью цифрового осциллографа типа PCSGU250.
Горизонтальная ось была установлена на 1 мс/деление, а вертикальная ось — на 1 В/деление.
Пиковое выходное напряжение составляет 2 В, как и ожидалось.
Рис. 6.29: Выходной сигнал.
Использование прерываний таймера для точного измерения времени
Как мы видели на рис. 6.29, период сигнала не равен точно 2 мс. В этом разделе мы будем
использовать прерывания таймера для достижения более точного измерения времени.
На рисунке 6.30 показан новый листинг программы (Программа: Square2). В этой версии
программы переменная с именем flag используется для попеременного вывода времени
включения и выключения. Таймер работает в фоновом режиме и вызывает функцию DAC
1000 раз в секунду (т.е. 500 импульсов включения и 500 импульсов выключения).
● 148
Chapter 6 • Amateur Radio Hardware-based Projects
#---------------------------------------------------------# Сгенерировать прямоугольный сигнал с амплитудой +2 В
#
================================================
#
# В этом проекте микросхема ЦАП типа MCP4921 подключена к
# Raspberry Pi Pico. Программа генерирует прямоугольный сигнал
# с частотой f=500 Гц, коэффициентом заполнения 50% (время
включения и выключения равно и составляет 1 мс каждое) и амплитудой 2 В.
#
# В этой версии программы используются прерывания по таймеру.
#
# Author: Dogan Ibrahim
# File
: Square2.py
# Date
: August 2021
#-----------------------------------------------------------from machine import Pin, SPI, Timer
#import utime
spi_sck = Pin(2)
# Контакт SCK на GP2
spi_tx = Pin(3)
# Контакт TX на GP3
spi_rx = Pin(0)
# Контакт RX на GP0 (не используется)
spi = SPI(0,sck=spi_sck,mosi=spi_tx,miso=spi_rx,baudrate=100000)
CS = Pin(16, Pin.OUT)
# CS
CS.value(1) # Отключить чип
ONvalue = int(2000 * 4095 / 3300)
# Для амплитуды +2 В
OFFvalue = 0
tim = Timer()
flag = 0
#
# подпрограмма обработки прерывания таймера
#
def DAC(timer):
global flag, Onvalue, OFFvalue
global CS
buff = [0, 0]
if flag == 0:
data = ONvalue
flag = 1
else:
data = OFFvalue
flag = 0
● 149
Raspberry Pi Pico for Radio Amateurs
buff[0] = (data >> 8) & 0x0F
# Старший байт
buff[0] = buff[0] + 0x30
buff[1] = data & 0xFF
# Младший байт
CS.value(0)
# Включить MCP4921
# Отправить на шину SPI
# Выключить MCP4921
spi.write(bytearray(buff))
CS.value(1)
#
# Основная программа
#
tim.init(freq = 1000, mode = Timer.PERIODIC, callback = DAC)
Рис. 6.30 Программа: Square2.
.
На рис. 6.31 показан новый выходной сигнал. Видно, что период сигнала составляет ровно 2
мс (т.е. частота ровно 500 Гц).
Рис. 6.31: Выходной сигнал.
6.6.2 Проект 6: Генерация фиксированных напряжений
В этом проекте мы будем использовать ЦАП для генерации фиксированных напряжений. Будут
генерироваться напряжения с амплитудами 0, 1, 2 и 3 В с задержкой 100 мс между каждым
напряжением. Блок-схема и принципиальная схема представлены на рис. 6.26 и рис. 6.27
соответственно.
На рис. 6.32 показан листинг программы (Программа:FixedV). Функция «Voltage» преобразует
напряжение в 12-битное цифровое значение и возвращает его в основную программу.
● 150
Chapter 6 • Amateur Radio Hardware-based Projects
#---------------------------------------------------------#
ГЕНЕРАЦИЯ ПОСТОЯННОГО НАПРЯЖЕНИЯ
#
=====================================
#
# В этом проекте микросхема ЦАП типа MCP4921 подключена к
# Raspberry Pi Pico. Программа генерирует фиксированные напряжения
# с амплитудами 0, 1 и 2 В и задержкой между выходными сигналами
# в 100 мс.
#
# Author: Dogan Ibrahim
# File
: FixedV.py
# Date
: February 2021
#-----------------------------------------------------------from machine import Pin, SPI
import utime
spi_sck = Pin(2)
# Контакт SCK на GP2
spi_tx = Pin(3)
# Контакт TX на GP3
spi_rx = Pin(0)
# Контакт RX на GP0 (не используется)
spi = SPI(0,sck=spi_sck,mosi=spi_tx,miso=spi_rx,baudrate=100000)
CS = Pin(16, Pin.OUT)
# CS
CS.value(1) # Отключить чип
def Voltage(V):
Amplitude = int(V * 4095 / 3300)
return Amplitude
def DAC(data):
buff = [0, 0]
buff[0] = (data >> 8) & 0x0F
# HIGH байт
buff[0] = buff[0] + 0x30
buff[1] = data & 0xFF
#LOW байт
CS.value(0)
# Включить MCP4921
spi.write(bytearray(buff))
# Отправить на шину SPI
CS.value(1)
# Выключить MCP4921
#
# Основная программа
#
while True:
DAC(Voltage(0))
utime.sleep_ms(100)
DAC(Voltage(1000))
utime.sleep_ms(100)
● 151
Raspberry Pi Pico for Radio Amateurs
DAC(Voltage(2000))
utime.sleep_ms(100)
DAC(Voltage(3000))
utime.sleep_ms(100)
Рис. 6.32: Программа: FixedV.
На рис. 6.33 показана сгенерированная выходная осциллограмма.
Рис. 6.33: Форма выходного сигнала.
6.6.3 Проект 7: Генерация пилообразного сигнала
В этом проекте мы будем использовать ЦАП для генерации пилообразного сигнала
со следующими характеристиками:
Peak voltage:
Step width:
Number of steps:
3.3 V
2 ms
10
Блок-схема и принципиальная схема снова представлены на рис. 6.26 и рис. 6.27
соответственно.
На рис. 6.34 показан листинг программы (Программа: Sawtooth). Функция «Напряжение»
преобразует напряжение в 12-битное цифровое значение и возвращает его в основную
программу. Обратите внимание, что, как описано ранее, синхронизация генерируемого
сигнала не является идеально точной, и для генерации точного выходного сигнала можно
использовать прерывания таймера.
● 152
Chapter 6 • Amateur Radio Hardware-based Projects
#---------------------------------------------------------#
СОЗДАНИЕ ПИЛООБРАЗНОГО СИГНАЛА
#
==================================
#
# В этом проекте микросхема ЦАП типа MCP4921 подключена к
# Raspberry Pi Pico. Программа генерирует пилообразный сигнал,
# имеющий 10 шагов.
#
# Author: Dogan Ibrahim
# File
: Sawtooth.py
# Date
: August 2021
#-----------------------------------------------------------from machine import Pin, SPI
import utime
spi_sck = Pin(2)
# Контакт SCK на GP2
spi_tx = Pin(3)
# Контакт TX на GP3
spi_rx = Pin(0)
# Контакт RX на GP0 (не используется)
spi = SPI(0,sck=spi_sck,mosi=spi_tx,miso=spi_rx,baudrate=100000)
CS = Pin(16, Pin.OUT)
# CS
CS.value(1) # Отключить чип
def Voltage(V):
Amplitude = int(V * 4095 / 3300)
return Amplitude
def DAC(data):
buff = [0, 0]
buff[0] = (data >> 8) & 0x0F
# HIGH байт
buff[0] = buff[0] + 0x30
buff[1] = data & 0xFF
# Младший байт
CS.value(0)
# Включить MCP4921
# Отправить на шину SPI
# Выключить MCP4921
spi.write(bytearray(buff))
CS.value(1)
#
# Основная программа
#
k = 0.0
while True:
DAC(int(Voltage(k*3300)))
utime.sleep_ms(2)
k = k + 0.1
if k == 1.0:
● 153
Raspberry Pi Pico for Radio Amateurs
k = 0.0
.
Рис. 6.34: Программа: Sawtooth.
На рис. 6.35 показана сгенерированная выходная форма сигнала. Здесь горизонтальная
ось соответствует 10 мс/деление, а вертикальная ось — 1 В/деление.
Рис. 6.35: Выходной сигнал.
6.6.4 Проект 8: Генерация треугольного сигнала
В этом проекте мы будем использовать ЦАП для генерации треугольного волнового сигнала с 10
шагами подъема и 10 шагами спуска. Ширина шага установлена на 1 мс. Блок-схема и
принципиальная схема представлены на рисунках 6.26 и 6.27 соответственно.
На рис. 6.36 показан листинг программы (Программа: Triangle). Функция «Voltage»
преобразует напряжение в 12-битное цифровое значение и возвращает его в основную
программу.
#----------------------------------------------------------
#
СОЗДАНИЕ СИГНАЛА ТРЕУГОЛЬНОЙ ФОРМЫ
# =====================================
#
# В этом проекте микросхема ЦАП типа MCP4921 подключена к
# Raspberry Pi Pico. Программа генерирует треугольный сигнал.
#
# Author: Dogan Ibrahim
# File : Triangle.py
# Date : August 2021
#-----------------------------------------------------------from machine import Pin, SPI
import utime
● 154
Chapter 6 • Amateur Radio Hardware-based Projects
spi_sck = Pin(2)
spi_tx = Pin(3)
spi_rx = Pin(0)
# Контакт SCK на GP2
# Контакт TX на GP3
# Контакт RX на GP0 (не используется)
spi = SPI(0,sck=spi_sck,mosi=spi_tx,miso=spi_rx,baudrate=100000)
CS = Pin(16, Pin.OUT)
# CS
CS.value(1) # Отключить чип
def Voltage(V):
Amplitude = int(V * 4095 / 3300)
return Amplitude
def DAC(data):
buff = [0, 0]
buff[0] = (data >> 8) & 0x0F
buff[0] = buff[0] + 0x30
buff[1] = data & 0xFF
CS.value(0)
spi.write(bytearray(buff))
CS.value(1)
# HIGH байт
# Младший байт
# Включить MCP4921
# Отправить на шину SPI
# Выключить MCP4921
#
# Основная программа
#
while True:
k = 0.0
while k < 1.0:
# подъём
DAC(int(Voltage(k*3300)))
utime.sleep_ms(1)
k = k + 0.1
k = 1.0
while k > 0.0:
DAC(int(Voltage(k*3300)))
utime.sleep_ms(1)
k = k - 0.1
# спад
Figure 6.36: Program: Triangle.
На рис. 6.37 показана сгенерированная выходная осциллограмма. Обратите внимание, что,
как было описано ранее, синхронизация генерируемого сигнала не является идеально точной,
и для генерации точного выходного сигнала можно использовать прерывания таймера.
● 155
Raspberry Pi Pico for Radio Amateurs
Рис. 6.37: Выходной сигнал.
6.6.5 Проект 9: Произвольная периодическая форма сигнала
В этом проекте мы сгенерируем произвольную периодическую форму сигнала с периодом
20 мс. Подробности формы сигнала показаны на рис. 6.38.
Рис. 6.38: Форма сигнала, который необходимо сгенерировать.
Форма сигнала принимает следующие значения:
Time (ms)
0
1
2
3
4
5
6
● 156
Amplitude (V)
0
0.2
0.4
0.6
0.8
1.0
1.2
Time (ms)
11
12
13
14
15
16
17
Amplitude (V)
1.6
1.6
1.4
1.2
1.0
0.8
0.6
Chapter 6 • Amateur Radio Hardware-based Projects
7
8
9
10
1.4
1.6
1.6
1.6
18
19
20
0.4
0.2
0.0
Блок-схема и принципиальная схема представлены на рисунках 6.26 и 6.27 соответственно.
На рис. 6.39 показан листинг программы (Программа: Arbitrary). Отсчеты напряжения
хранятся в списке с именем «Waveform». Внутри основной программы цикл выполняется от
0 до 20 (включительно), получает требуемую амплитуду напряжения на каждом отсчете и
вызывает ЦАП для генерации требуемого отсчета.
#---------------------------------------------------------#
ГЕНЕРАЦИЯ СИГНАЛА ПРОИЗВОЛЬНОЙ ФОРМЫ
#
==========================================
#
# В этом проекте микросхема ЦАП типа MCP4921 подключена к
# Raspberry Pi Pico. Программа генерирует произвольный сигнал,
# характеристики которого описаны в тексте.
#
# Author: Dogan Ibrahim
# File
: Arbitrary.py
# Date
: August 2021
#-----------------------------------------------------------from machine import Pin, SPI
import utime
import math
spi_sck = Pin(2)
# Контакт SCK на GP2
spi_tx = Pin(3)
# Контакт TX на GP3
spi_rx = Pin(0)
# Контакт RX на GP0 (не используется)
spi = SPI(0,sck=spi_sck,mosi=spi_tx,miso=spi_rx,baudrate=100000)
CS = Pin(16, Pin.OUT)
# CS
# Отключить чип
CS.value(1)
Waveform = [0.0,0.2,0.4,0.6,0.8,1.0,1.2,1.4,1.6,1.6,1.6,1.6,1.6,
1.4,1.2,1.0,0.8,0.6,0.4,0.2,0.0]
def Voltage(V):
Amplitude = int(V * 4095 / 3.3)
return Amplitude
def DAC(data):
● 157
Raspberry Pi Pico for Radio Amateurs
buff = [0, 0]
buff[0] = (data >> 8) & 0x0F
# HIGH байт
buff[0] = buff[0] + 0x30
buff[1] = data & 0xFF
# Младший байт
CS.value(0)
# Включить MCP4921
# Отправить на шину SPI
# Выключить MCP4921
spi.write(bytearray(buff))
CS.value(1)
#
# Основная программа
#
while True:
for k in range(21):
DAC(int(4095*Waveform[k]/3.3))
utime.sleep_ms(1)
Рис. 6.39: Программа: Arbitrary.
На рис. 6.40 показана сгенерированная выходная осциллограмма. Обратите внимание, что,
как было описано ранее, синхронизация генерируемого сигнала не является идеально точной,
и для генерации точного выходного сигнала можно использовать прерывания таймера.
Рис. 6.40: Выходной сигнал.
6.6.6 Проект 10: Генерация синусоидального сигнала
В этом проекте мы будем генерировать синусоидальный сигнал, используя
тригонометрические функции. Сгенерированный синусоидальный сигнал должен
иметь амплитуду от пика до пика 1,4 В, частоту 50 Гц и смещение 1 В.
Блок-схема и принципиальная схема представлены на рис. 6.26 и рис. 6.27
соответственно.
● 158
Chapter 6 • Amateur Radio Hardware-based Projects
Листинг программы: Поскольку требуемая частота составляет 50 Гц, период равен 20 мс или
20 000 мкс. Если предположить, что синусоидальный сигнал состоит из 100 отсчетов, то
каждый отсчет должен выводиться с интервалом 20 000 / 100 = 200 мкс.
Функция синусоидального сигнала имеет следующий формат:
Offset + PeaktoPeak / 2 × sin(2 × π × Count / T)
где T — период сигнала, равный 100 отсчетам. Count — переменная, изменяющаяся от 0 до
100 и увеличивающаяся на 1, PeaktoPeak — амплитуда от пика до пика, а Offset —
смещениепостоянного тока. Это необходимо, поскольку синусоидальный сигнал имеет
отрицательныезначения, а ЦАП выдает только положительные значения, поэтому нам нужно
сдвинутьсинусоидальный сигнал вверх на величину смещения постоянного тока.
Сумма напряжения Offset и Amplitude не должна превышать +3,3 В, что является
максимальным выходным напряжением, которое может выдавать ЦАП, т.е.:
Offset + PeaktoPeak <= +3.3 V
Фактически требуемое смещение постоянного тока равно:
Required DC offset = Offset – PeaktoPeak / 2. Следовательно, в приведенной выше
формуле смещение рассчитывается следующим образом:
Offset = Required DC offset + PeaktoPeak/2
Синусоидальный сигнал делится на 100 отсчетов, и каждый отсчет выводится с интервалом в
200 мкс.
Формулу синуса можно записать следующим образом:
Required DC offset + PeaktoPeak/2 + PeaktoPeak / 2 × sin(0.0628 × Count)
Таким образом, при каждом выборе значения мы будем вычислять и
выводить его на ЦАП:
На рис. 6.41 показан листинг программы (Программа: Sine). В начале программы
определяются амплитуда от пика до пика и смещение, которые затем преобразуются в
цифровые значения для ЦАП. Значения синуса вычисляются вне цикла программы и
сохраняются в списках sin для экономии времени. Внутри основной программы отсчеты синуса
отправляются на ЦАП, а затем выводятся.
● 159
Raspberry Pi Pico for Radio Amateurs
#---------------------------------------------------------#
ГЕНЕРАЦИЯ СИНУСОИДАЛЬНОГО СИГНАЛА
#
======================================
#
# В этом проекте микросхема ЦАП типа MCP4921 подключена к
# Raspberry Pi Pico.
Программа генерирует синусоидальный сигнал с
# характеристиками, указанными в тексте.
#
# Author: Dogan Ibrahim
# File
: Sine.py
# Date
: August 2021
#-----------------------------------------------------------from machine import Pin, SPI
import utime
import math
spi_sck = Pin(2) # Контакт SCK на GP2
spi_tx = Pin(3) # Контакт TX на GP3
spi_rx = Pin(0) # Контакт RX на GP0 (не используется)
spi = SPI(0,sck=spi_sck,mosi=spi_tx,miso=spi_rx,baudrate=100000)
CS = Pin(16, Pin.OUT)
# CS
CS.value(1) # Отключить чип
R = 0.0628
T = 100
Conv = 4095.0 / 3.3
PeaktoPeak = 1.4 * Conv
# 1.4V
ReqDCoffset = 1.0 * Conv
# 1.6V
def DAC(data):
buff = [0, 0]
buff[0] = (data >> 8) & 0x0F
# HIGH байт
buff[0] = buff[0] + 0x30
buff[1] = data & 0xFF
# Младший байт
CS.value(0)
# Включить MCP4921
spi.write(bytearray(buff))
# Отправить на шину SPI
CS.value(1)
# Выключить MCP4921
#
# Основная программа
#
sins=[0]*101
for i in range (101):
● 160
Chapter 6 • Amateur Radio Hardware-based Projects
sins[i] = ReqDCoffset+PeaktoPeak/2 + PeaktoPeak/2 * math.sin(R*i)
while True:
for k in range(101):
value = sins[k]
DAC(int(value))
utime.sleep_us(200)
Рис. 6.41: Программа: Sine.
На рис. 6.42 показана сгенерированная выходная форма сигнала. Здесь горизонтальная ось
соответствует 20 мс/деление, а вертикальная — 1 В/деление. Смещение и амплитуда
сигнала верны, но, как описано ранее, синхронизация генерируемого сигнала не является
идеально точной, и для генерации точного выходного сигнала можно использовать
прерывания таймера.
Рис. 6.42: Выходной сигнал.
6.6.7 Проект 11: Генерация точного синусоидального сигнала с использованием
прерываний таймера
В этом проекте мы будем генерировать точный синусоидальный сигнал с помощью
прерываний таймера. Требуемая амплитуда от пика до пика составляет 1,4 В, требуемое
смещение — 1 В, а требуемая частота — 50 Гц (период = 20 мс). В этом проекте мы будем
брать 50 отсчетов вместо 100, так что длительность каждого отсчета составит 400 мкс. В этой
программе прерывание таймера настроено с функцией обратного вызова ЦАП и частотой 2500
Гц (т.е. 400 мкс на каждый вызов). Внутри функции ЦАП данные отсчетов индексируются
переменной k, которая увеличивается при каждом прерывании. Затем эти отсчеты выводятся
ЦАП.
На рис. 6.43 показан листинг программы (Программа:Sineint).
● 161
Raspberry Pi Pico for Radio Amateurs
#---------------------------------------------------------#
ГЕНЕРАЦИЯ СИНУСОИДАЛЬНОГО СИГНАЛА
#
=====================================
#
# В этом проекте микросхема ЦАП типа MCP4921 подключена к
# Raspberry Pi Pico. Программа генерирует синусоидальный сигнал с
# характеристиками, указанными в тексте.
#
# Эта программа использует прерывания таймера для точного измерения времени.
#
# Author: Dogan Ibrahim
# File
: Sineint.py
# Date
: August 2021
#-----------------------------------------------------------from machine import Pin, SPI, Timer
import utime
import math
tim = Timer()
spi_sck = Pin(2)
# Контакт SCK на GP2
spi_tx = Pin(3)
# Контакт TX на GP3
spi_rx = Pin(0)
# Контакт RX на GP0 (не используется)
spi = SPI(0,sck=spi_sck,mosi=spi_tx,miso=spi_rx,baudrate=100000)
CS = Pin(16, Pin.OUT)
# CS
CS.value(1) # Отключить чип
R = 2 * 3.14159/50
T = 100
Conv = 4095.0 / 3.3
PeaktoPeak = 1.4 * Conv
# 1.4V
ReqDCoffset = 1.0 * Conv
# 1.6V
k = 0
def DAC(timer):
global k, CS, sins
buff = [0, 0]
k = k + 1
if k == 50:
k = 0
data = int(sins[k])
buff[0] = (data >> 8) & 0x0F
# HIGH байт
buff[0] = buff[0] + 0x30
buff[1] = data & 0xFF
# Младший байт
CS.value(0)
# Включить MCP4921
● 162
Chapter 6 • Amateur Radio Hardware-based Projects
spi.write(bytearray(buff))
# Отправить на шину SPI
CS.value(1)
# Выключить MCP4921
#
# Основная программа
#
sins=[0]*101
for i in range (101):
sins[i] = ReqDCoffset+PeaktoPeak/2 + PeaktoPeak/2 * math.sin(R*i)
tim.init(freq=2500, mode = Timer.PERIODIC, callback = DAC)
Рис. 6.43: Программа: Sineint.
На рис. 6.44 показана выходная осциллограмма. Здесь горизонтальная ось соответствует 10
мс/деление, а вертикальная — 1 В/деление. Видно, что период осциллограммы составляет
ровно 20 с, как и требовалось, смещение равно 1 В, а амплитуда от пика до пика — 1,4 В.
Рис. 6.44: Выходной сигнал.
6.7 Генерация сигналов — с использованием аппаратного обеспечения
В некоторых приложениях может потребоваться генерация точных сигналов. В этом
разделе мы будем использовать программируемый модуль генератора сигналов для
генерации точных синусоидальных и прямоугольных сигналов.
● 163
Raspberry Pi Pico for Radio Amateurs
6.7.1 Проект 12: Генератор сигналов фиксированной частоты
Мы будем использовать популярный модуль генератора сигналов AD9850 вместе с Raspberry
Pi Pico. Модуль AD9850 (рис. 6.45) представляет собой двойной генератор синусоидальных и
прямоугольных сигналов со следующими характеристиками:
•
•
•
•
•
•
•
синусоидальный выход 0–40 МГц
прямоугольный выход 0–1 МГц
работа от 3,3 В или 5 В
встроенный кварцевый резонатор 125 МГц
встроенный 10-битный ЦАП
последовательное или параллельное программирование данных
рабочий ток 60 мА
Рис. 6.45: Модуль AD9850.
Архитектура схемы AD9850 позволяет генерировать выходные частоты до половины
опорной тактовой частоты (или 62,5 МГц). Устройство также обеспечивает пятибитную
цифровую фазовую модуляцию, которая позволяет сдвигать фазу выходного сигнала с
шагом 180°, 90°, 45°, 22,5°, 11,25° и любой их комбинацией.
В этом проекте мы будем генерировать синусоидальный сигнал частотой 1 кГц
в качестве примера.
Перед использованием AD9850 в проекте необходимо знать, как его программировать, что
кратко описано в следующих разделах (более подробную информацию об AD9850 можно
получить в техническом описании производителя по адресу:
https://www.analog.com/media/en/technical-documentation/data-sheets/ad9850.pdf)
На рис. 6.46 показана распиновка AD9850.
● 164
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.46: Распиновка модуля AD9850.
Обозначения выводов:
VCC: питание (3.3 V or 5 V)
GND: земля
W_CLK: тактовый сигнал загрузки слова
FQ_UD: обновление частоты (частота или фаза обновляются
по восходящему фронту этого вывода)
DATA: вывод последовательной загрузки
RESET: вывод главного сброса (ВЫСОКИЙ уровень для сброса всех регистров)
D0-D7: параллельный вход данных (для загрузки 32-битного слова частоты и
8-битного слова фазы/управления)
Square Wave Output1: выход прямоугольного сигнала 1 (выход компаратора)
Square Wave Output2: ... 2 (выход компаратора в инвертированном виде)
Sine Wave Output1: аналоговый выход синусоидального сигнала 2
(выход ЦАП в инвертированном виде)
Sine Wave Output2: аналоговый выход синусоидального сигнала 2
(выход ЦАП в инвертированном виде)
Встроенный потенциометр используется для установки коэффициента заполнения
прямоугольной волны.
Микросхема AD9850 может работать как в параллельном, так и в последовательном
режиме. В этом проекте мы будем использовать последовательный режим.
На рис. 6.47 показана блок-схема проекта. Синусоидальный выход 1 модуля
подключен к осциллографу.
● 165
Raspberry Pi Pico for Radio Amateurs
Рис. 6.47: Блок-схема проекта.
Схема подключения проекта показана на рис. 6.48. Между Raspberry Pi Pico и модулем
AD9850 выполнены следующие соединения:
AD9850 module
Raspberry Pi Pico
FQ_UD GP10 (pin 14)
W_CLK
GP11 (pin 15)
RESET
GP12 (pin 16)
DATA
GP13 (pin 17)
Рис. 6.48: Схема проекта.
Взаимосвязь между выходной частотой, опорным тактовым сигналом и настроечным словом
AD9850 определяется следующей формулой:
Fout = ∆Phase × REFCLOCK / 232
или
∆Phase = Fout × 232 /REFCLOCK
где Fout — выходная частота в МГц, ∆Phase — значение 32-битного настроечного слова, а
REFCLOCK — опорный тактовый сигнал в МГц. Выходной синусоидальный сигнал представляет
собой аналоговый сигнал, выводимый 10-битным ЦАП. Обратите внимание, что 232 = 4 294 967
296.
● 166
Chapter 6 • Amateur Radio Hardware-based Projects
Микросхема AD9850 содержит 40-битный регистр, состоящий из 32-битного слова управления
частотой, 5-битного слова фазовой модуляции и функции понижения энергопотребления. В этом
проекте регистр загружается последовательно. В этом режиме восходящий фронт сигнала W_CLK
сдвигает 1-битные данные на выводе D7 (DATA) через 40 бит программной информации. После
сдвига на 40 бит требуется импульс FQ_UD для обновления выходной частоты (или фазы).
Последовательный режим включается следующей последовательностью
(см. техническое описание, стр. 12, рис. 10):
• импульс RESET
• импульс W_CLK
• импульс FQ_UD
40-битные последовательные данные загружаются следующим образом:
•
•
•
•
•
•
•
•
•
•
•
•
•
•
бит отправки 0 - частота (младший бит)
бит отправки 1 - частота
бит отправки 2 - частота
……….
……….
бит отправки 31 — частота (старший бит)
бит отправки 32 — управление (устанавливается в 0)
бит отправки 33 — управление (устанавливается в 0)
бит отправки 34 — отключение питания
бит отправки 35 — фаза (младший бит)
бит отправки 36 — фаза
бит отправки 37 — фаза
бит отправки 38 — фаза
бит отправки 39 — фаза (старший бит)
На рис. 6.49 показан листинг программы (Программа: freqgen.py). В начале программы
соединения выводов AD9850 FQ_UD, W_CLK, RESET и DATA устанавливаются на 26, 19, 13
и 6 соответственно, что соответствует именам выводов GPIO. Эти выводы настроены как
выходы, и все они обнуляются в начале программы.
Программа состоит из ряда функций, описанных ниже:
SendPulse: Эта функция отправляет сигналы логического уровня HIGH-LOW на вывод,
указанный в её аргументе GPIOpin.
SendByte: Эта функция принимает байт в качестве аргумента. Затем формируется цикл для
отправки 8 бит этого байта на последовательный вход DATA. После отправки бита на
вывод W_CLK отправляется импульс.
SetSerialMode: Эта функция переводит AD9850 в последовательный режим, подавая
импульсы на контакты RESET, W_CLK и FQ_UD.
● 167
Raspberry Pi Pico for Radio Amateurs
Функция LoadFrequency принимает в качестве аргумента требуемую частоту. Затем
вычисляется настроечное слово по формуле, описанной ранее в этом разделе, и
сохраняется в переменной f. После этого формируется цикл for, который повторяется 4 раза.
Младший байт переменной f затем отправляется в функцию SendByte, позволяя передать ее
8 бит на последовательный вход. Затем переменная f сдвигается вправо 8 раз, так что
следующий старший байт сериализуется и отправляется в функцию SendByte. Этот процесс
повторяется для 4 байтов, в общей сложности 32 бита. Затем оставшиеся 8 бит
отправляются как нули, так что два управляющих слова равны 0, а также биты фазы равны 0.
Основная программа переводит AD9850 в последовательный режим, устанавливает
требуемую частоту в Гц (1000 Гц = 1 кГц) и загружает частоту в AD9850, вызывая функцию
LoadFrequency.
Программа завершается при нажатии комбинации клавиш Ctrl+C на клавиатуре ПК. Перед
завершением программы микроконтроллер AD9850 останавливается.
#----------------------------------------------------------------#
ГЕНЕРАТОР ЧАСТОТЫ
#
===================
#
# В этой программе модуль AD9850 подключен к Raspberry Pi Pico.
# Программа генерирует синусоидальный сигнал с частотой 1 кГц.
# Встроенный кварцевый резонатор модуля AD9850 имеет частоту 125 МГц.
#
# Author: Dogan Ibrahim
# File
: freqgen.py
# Date
: August, 2021
#------------------------------------------------------------------from machine import Pin
#
# AD9850 module connections
#
FQ_UD = Pin(10, Pin.OUT)
# FQ_UD pin
W_CLK = Pin(11, Pin.OUT)
# W_CLK pin
RESET = Pin(12, Pin.OUT)
# RESET pin
DATA =
# DATA pin
Pin(13, Pin.OUT)
#
# Set all outputs to 0 at the beginning
#
FQ_UD.value(0)
W_CLK.value(0)
RESET.value(0)
DATA.value(0)
#
● 168
Chapter 6 • Amateur Radio Hardware-based Projects
# Эта функция посылает импульс на контакт, указанный в аргументе.
#
def SendPulse(GPIOpin):
GPIOpin.value(1)
GPIOpin.value(0)
return
#
# Эта функция отправляет биты байта данных в модуль AD9850.
#
def SendByte(DataByte):
for k in range(0, 8):
# Повторить 8 раз
p = DataByte & 0x01
# Получить бит 0
DATA.value(p)
# Вывести его
SendPulse(W_CLK)
# Отправить тактовый сигнал
DataByte = DataByte >> 1
# Получить следующий бит
return
#
# Эта функция переводит модуль AD9850 в последовательный режим.
#
def SetSerialMode():
SendPulse(RESET)
# Импульс RESET
SendPulse(W_CLK)
# Импульс W_CLK
SendPulse(FQ_UD)
# Импульс FQ_UD
return
#
# Эта функция загружает 40-битные данные в AD9850. Затем
# отправляются 32-битные данные частоты, после чего бит
# понижения мощности отправляется как 0, два управляющих бита
# отправляются как 0, а затем 5 фазовых битов отправляются как 0.
#
def LoadFrequency(frequency):
f = int(frequency * 4294967296 / 125000000) # See book
for p in range(0, 4):
# Повторить 4 раза
SendByte(f & 0xFF)
# Отправить младший байт
f = f >> 8
# Получить следующий байт
SendByte(0x00)
SendPulse(FQ_UD)
# Отправить оставшиеся биты
# Завершить последовательный порт
return
try:
SetSerialMode()
# Выберите последовательный режим
RequiredFrequency = 1000
# требуется 1000 Гц
● 169
Raspberry Pi Pico for Radio Amateurs
LoadFrequency(RequiredFrequency)
# Загрузить регистр
while True:
# Ждать вечно...
pass
# ...пока не остановят
except KeyboardInterrupt:
# Клавиатура Ctrl+C
SendPulse(RESET)
# Остановить AD9850
Рис. 6.49: Программа: freqgen.py..
На рис. 6.50 показан проект, собранный на макетной плате.
Рис. 6.50: Проект, собранный на макетной плате.
Пример выходного сигнала программы показан на рис. 6.51. Как видно из этого рисунка,
частота сигнала составляет ровно 1 кГц, как и требуется. Выходной сигнал измеряется с
вывода Sineoutput1. Пиковая амплитуда сигнала была измерена и составила ровно 1 В.
● 170
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.51: Пример отображения синусоидального сигнала, полученного из программы.
На рис. 6.52 показан прямоугольный сигнал, полученный программой, измеренный с вывода
Squareoutput2. Коэффициент заполнения сигнала можно регулировать с помощью
потенциометра. Амплитуда сигнала составила 3,3 В.
Рис. 6.52: Пример отображения прямоугольной волны из программы.
6.7.2 Проект 13: Генерация сигналов с вводом частоты с клавиатуры и
ЖК-дисплея
Этот проект аналогичен предыдущему, но здесь для установки частоты сигнала используются
клавиатура и ЖК-дисплей с интерфейсом I2C. Это делает проект автономным, так что Raspberry
Pi Pico может использоваться самостоятельно, без необходимости использования
ПК для установки частоты сигнала.
●
171
Raspberry Pi Pico for Radio Amateurs
На рис. 6.53 представлена блок-схема проекта.
Рис. 6.53: Блок-схема проекта.
Клавиатура: В проектах на базе микроконтроллеров можно использовать несколько типов
клавиатур. В этом проекте используется клавиатура 4×4 (Рис. 6.54). Эта клавиатура имеет
клавиши для цифр от 0 до 9, букв A, B, C, D, а также символов * и #. Клавиатура подключена
к процессору с помощью 8 проводов, называемых R1–R4 и C1–C4, которые представляют
собой строки (R) и столбцы (C) клавиатуры соответственно (см. Рис. 6.55).
Рис. 6.54: клавиатура 4×4.
● 172
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.55: Схема интерфейса клавиатуры 4×4.
Работа клавиатуры довольно проста: столбцы настроены как выходы, а строки — как входы.
Нажатая клавиша определяется с помощью сканирования столбцов. При этом один столбец
принудительно устанавливается в низкий логический уровень, в то время как другие столбцы
остаются в высоком логическом уровне. Затем сканируется состояние каждой строки, и если
строка оказывается в низком состоянии, то клавиша в точке пересечения с этой строкой
идентифицируется как нажатая. Этот процесс повторяется для всех строк.
На рис. 6.56 показана принципиальная схема проекта. ЖК-дисплей I2C подключен к Raspberry
Pi, как и в предыдущих проектах, при этом контакты GPIO 2 и GPIO 3 используются в качестве
выводов SDA и SCL соответственно. Модуль AD9850 подключен так же, как и в предыдущем
проекте. Клавиатура 4×4 подключена к следующим контактам GPIO Raspberry Pi Pico.
Контакты строк удерживаются в высоком состоянии с помощью внутренних подтягивающих
резисторов к +3,3 В:
Keypad pin
Raspberry Pi pin
R1
GP4
R2
GP5
R3
GP6
R4
GP7
C1
GP8
C2
GP9
C3
GP16
C4
GP17
● 173
Raspberry Pi Pico for Radio Amateurs
Рис. 6.56: Схема подключения проекта.
На рис. 6.57 показана конфигурация контактов клавиатуры 4×4, использованной в проекте.
Рис. 6.57: Конфигурация контактов клавиатуры 4×4.
Тестовая программа
Прежде чем писать программу для проекта, мы сначала напишем код для считывания
клавиш с клавиатуры, чтобы убедиться в правильной работе аппаратного и программного
обеспечения клавиатуры.
● 174
Chapter 6 • Amateur Radio Hardware-based Projects
Основные шаги для чтения клавиш следующие:
Настройте все столбцы как выходные данные
Настройте все строки как входные данные
Установите значение 1 для всех столбцов
DO for all columns
Set a column to 0
DO for all rows
IF a row is 0 THEN
Return the key at this column and row position
ENDIF
ENDDO
ENDDO
На рис. 6.58 показана тестовая программа (программа: keypad.py). В начале программы
определяются клавиши клавиатуры после импорта необходимых модулей. Соединения строк
и столбцов клавиатуры определяются с помощью списков ROWS и COLS соответственно.
Затем столбцы настраиваются как выходы и устанавливаются в 1. Аналогично, строки
настраиваются как входы. Функция Get_Key считывает нажатую клавишу и возвращает ее
вызывающей программе. В функции используются два цикла for: первый цикл выбирает
столбцы и устанавливает их в 0 один за другим. Второй цикл сканирует строки и проверяет,
находится ли строка в состоянии 0. Основная программа вызывает функцию и отображает
нажатую клавишу на экране. Вам следует оценить аппаратное и программное обеспечение
клавиатуры, нажимая различные клавиши на клавиатуре и проверяя, отображается ли
правильная клавиша на экране ПК.
#-------------------------------------------------------------#
ПРОГРАММА ТЕСТИРОВАНИЯ КЛАВИАТУРЫ
#
======================================
#
# Эта программа демонстрирует, как использовать клавиатуру
# для отображения нажатых клавиш.
#
# Author: Dogan Ibrahim
# File
: keypad.py
# Date
: August 2021
#------------------------------------------------------------from machine import Pin
import utime
C = [0]*4
R = [0]*4
KEYPAD = [ #клавиши клавиатуры
[1,2,3,"A"],
[4,5,6,"B"],
[7,8,9,"C"],
● 175
Raspberry Pi Pico for Radio Amateurs
["*",0,"#","D"]]
ROWS = [4,5,6,7]
# пины для строк
COLS = [8,9,16,17]
# пины для столбцов
for i in range(4):
# конфиг. столбцов
C[i] = Pin(COLS[i], Pin.OUT)
C[i].value(1)
for j in range(4):
# Конфиг. строки
R[j] = Pin(ROWS[j], Pin.IN, Pin.PULL_UP)
#
# Эта функция считывает нажатие клавиши с клавиатуры.
#
def Get_Key():
while True:
for j in range(4):
C[j].value(0)
# Установить столбец j в 0
for i in range(4):
# Для всех строк
if R[i].value() == 0:
# Строка равна 0?
return (KEYPAD[i][j])
while R[i].value() == 0:
pass
C[j].value(1)
# Колонка возвращается к 1
utime.sleep(0.05)
# ждите 0,05 с
while True:
key = Get_Key()
# использ.
print(key)
# Отобразить клавишу
клавишу
utime.sleep(0.5)
Рис. 6.58: Программа: keypad.py.
Теперь мы должны приступить к разработке программы этого проекта. На рис. 6.59 показан
листинг программы (программа: keypadsig.py). В этой программе клавиша D считается
клавишей ENTER, и все вводимые данные на клавиатуре должны завершаться нажатием
клавиши ENTER.
В начале программы импортируются используемые библиотечные модули. Затем
определяется расположение клавиш на клавиатуре. Столбцы клавиатуры настраиваются
как выходы, а ее строки — как входы. Функция Get_Key принимает клавишу с клавиатуры и
возвращает ее в основную программу.
Часть программы, отвечающая за модуль AD9850, аналогична той, что использовалась
в предыдущем проекте.
● 176
Chapter 6 • Amateur Radio Hardware-based Projects
Внутри основного цикла программы вызывается функция Get_Key для получения номеров
клавиш, введенных пользователем. Программа принимает только клавиши от 0 до 9 и клавишу
D. Нажатие любой другой клавиши игнорируется программой. При нажатии клавиши Dis
программа сохраняет введенную частоту в переменной Total, которая затем копируется в
переменную frequency. После нажатия клавиши D на ЖК-дисплее отображается OK,
подтверждающее, что введенное значение частоты принято программой. После задержки в 5
секунд вторая строка ЖК-дисплея очищается, чтобы он был готов к приему нового значения
частоты.
Как и в предыдущем проекте, AD9850 переводится в последовательный режим, и
загружается введенная пользователем частота для генерации необходимой формы сигнала.
#--------------------------------------------------------------------------------#
Генератор частоты с клавиатурой и ЖК-дисплеем
#
==========================================
#
# В этой программе требуемая частота вводится с клавиатуры в Гц.
# Для отображения введенной частоты используется ЖК-дисплей.
#
# Author: Dogan Ibrahim
# File
: keypadsig.py
# Date
: Sept 2021
#------------------------------------------------------------from machine import I2C, Pin
import utime
from pico_i2c_lcd import I2cLcd
#
# Модуль ЖК-дисплея I2C, подключенный к SDA1, SCL1
#
i2c_lcd = I2C(id=1,scl=Pin(3),sda=Pin(2),freq=100000)
lcd = I2cLcd(i2c_lcd, 0x27, 2, 16)
C = [0]*4
R = [0]*4
KEYPAD = [
# Клавиши клавиатуры
[1,2,3,"A"],
[4,5,6,"B"],
[7,8,9,"C"],
["*",0,"#","D"]]
ROWS = [4,5,6,7]
# Пины для строк
COLS = [8,9,16,17]
# Пины для столбцов
for i in range(4):
# Конфиг. столбцов
C[i] = Pin(COLS[i], Pin.OUT)
● 177
Raspberry Pi Pico for Radio Amateurs
C[i].value(1)
for j in range(4):
# Конфиг. рядов
R[j] = Pin(ROWS[j], Pin.IN, Pin.PULL_UP)
#
# This function reads a key from the keypad
#
def Get_Key():
while True:
for j in range(4):
C[j].value(0)
# Установить столбец j в 0
for i in range(4):
# Для всех строк
if R[i].value() == 0:
return (KEYPAD[i][j])
# Строка равна 0?
# Клавиша Enter
while R[i].value() == 0:
pass
C[j].value(1)
# Столбец возвращается к 1
utime.sleep(0.05)
# Ждите 0,05 с
#
# ================ функции AD9850 ===================
#
# Подключения модуля AD9850
#
FQ_UD = Pin(10, Pin.OUT)
# FQ_UD pin
W_CLK = Pin(11, Pin.OUT)
# W_CLK pin
RESET = Pin(12, Pin.OUT)
# RESET pin
DATA =
# DATA pin
Pin(13, Pin.OUT)
#
# В начале установите все выходные значения равными 0.
#
FQ_UD.value(0)
W_CLK.value(0)
RESET.value(0)
DATA.value(0)
#
# Эта функция посылает импульс на контакт, указанный в аргументе.
#
def SendPulse(GPIOpin):
GPIOpin.value(1)
GPIOpin.value(0)
return
● 178
Chapter 6 • Amateur Radio Hardware-based Projects
#
# Эта функция отправляет биты байта данных в модуль AD9850.
#
def SendByte(DataByte):
for k in range(0, 8):
# Повторить 8 раз
p = DataByte & 0x01
# Получить бит 0
DATA.value(p)
# Вывести его
SendPulse(W_CLK)
# Отправить тактовый сигнал
DataByte = DataByte >> 1
# Получить следующий бит
return
#
# Эта функция переводит модуль AD9850 в последовательный режим.
#
def SetSerialMode():
SendPulse(RESET)
# Импульс RESET
SendPulse(W_CLK)
# Импульс W_CLK
SendPulse(FQ_UD)
# Импульс FQ_UD
return
#
# Эта функция загружает 40-битные данные в AD9850. 32-битные
# данные частоты передаются, затем бит выключения питания
# передаёт значение 0, два бита управления передаются как 0,
# а затем 5 битов фазы передаются как 0
#
def LoadFrequency(frequency):
f = int(frequency * 4294967296 / 125000000) # См. книгу
for p in range(0, 4):
# Повторить 4 раза
SendByte(f & 0xFF)
# Отправить младший байт
f = f >> 8
# Получить следующий байт
SendByte(0x00)
# Отправить оставшиеся биты
SendPulse(FQ_UD)
# Завершить серию
return
Total = 0
lcd.clear() # Очистить ЖК-дисплей
lcd.move_to(0, 0)
# В (0,0)
lcd.putstr("Frequency (Hz):")
# Направление
lcd.move_to(0, 1)
# To (0,1)
try:
while True:
lcd.move_to(0, 1)
flag = 0
● 179
Raspberry Pi Pico for Radio Amateurs
while flag == 0:
key = Get_Key()
# нажать на клавишу
if key != "D":
# это ENTER?
if str(key) >= "0" and str(key) <= "9":
#
if str(key).isnumeric():
lcd.putstr(str(key))
# Это число?
# Отображаемая клавиша
N = int(key)
Total = 10*Total + N
else:
frequency = Total
# Всего на данный момент
# Обнаружено ENTER
# Получить частоту
Total = 0
flag = 1
lcd.putstr("
- OK")
utime.sleep(0.2)
# показать OK
# ждите 0,2 сек
SetSerialMode() # Выбрать последовательный режим
LoadFrequency(frequency) # Загрузить регистр
utime.sleep(5)
lcd.move_to(0, 1)
lcd.putstr("
")
except KeyboardInterrupt:
SendPulse(RESET)
# Keyboard Cntrl+C
# Stop AD9850
Рис. 6.59: Программа: keypadsig.py..
На рис. 6.60 показан ЖК-дисплей до ввода частоты, после ввода частоты и после нажатия
клавиши D (ENTER) соответственно.
Рис. 6.60: Перед вводом частоты.
● 180
Chapter 6 • Amateur Radio Hardware-based Projects
Проект был собран на макетной плате, а соединения с RaspberryPi Pico и другими
компонентами осуществлялись с помощью перемычек. Заинтересованные читатели могут
самостоятельно разработать печатную плату для проекта.
На рис. 6.61 показана сгенерированная форма сигнала на осциллографе. Видно, что частота
составляет ровно 2000 Гц.
Рис. 6.61: Изображение на осциллографе.
Для увеличения уровня сигнала к выходу можно подключить ВЧ-усилитель.
6.8 Проект 14: Частотомер
Существует множество радиолюбительских задач, в которых требуется знать частоту сигнала.
Частотомеры — один из важных приборов, используемых практически всеми радиолюбителями.
Без частотомера единственным способом узнать частоту сигнала является использование
осциллографа. В этом проекте мы будем использовать Raspberry Pi Pico для разработки схемы
частотомера. Частота измеряемого сигнала будет отображаться на ЖК-дисплее с интерфейсом
I2C.
Измеряемый сигнал сначала преобразуется в прямоугольный сигнал для упрощения
взаимодействия с процессором. Существует три основных метода измерения частоты сигнала,
описанных ниже.
Измерение периода: при использовании этого метода сигнал подается на один из цифровых
выводов процессора. Процессор измеряет период сигнала с помощью внутреннего таймера. В
данном случае таймер запускается по переднему фронту сигнала и останавливается по
следующему переднему фронту. Зная период, мы затем вычисляем его обратную величину для
вычисления частоты. Хотя этот метод может дать точные результаты, он требует абсолютно
точного таймера. Raspberry Pi Pico — это микроконтроллер без операционной системы, и его
внутренний таймер не очень хорошо подходит для измерения частоты этим методом.
● 181
Raspberry Pi Pico for Radio Amateurs
Измерение импульсов (внутренний таймер): При использовании этого метода внутренний
таймер используется в качестве затвора. Процессор запускает таймер с известной
длительностью (например, одна секунда) и подсчитывает количество импульсов,
полученных за этот период времени. Затем, исходя из этого значения, вычисляется частота.
Например, если время затвора составляет одну секунду, то количество импульсов прямо
пропорционально частоте сигнала. Этот метод требует наличия внутреннего счётчика
процессора, который может обновляться внешним сигналом, и не подходит для Raspberry Pi
Pico.
Измерение импульсов (внешний таймер): В данном случае внешний чип-счётчик
используется для подсчёта количества импульсов за заданный промежуток времени. Затем
этот счёт считывается процессором, и частота легко вычисляется. В данном проекте мы
будем использовать этот третий метод. На рис. 6.62 показана блок-схема проекта.
Рис. 6.62: Блок-схема проекта.
В этом проекте используется микросхема счётчика типа SN74LV8154. Основные характеристики
этой микросхемы:
•
•
•
•
двойной 16-битный счётчикы
возможность использования в качестве 32-битного счётчика
рабочее напряжение от 2 до 5,5 В
вход сброса таймера
Преимущество этого таймера заключается в том, что его можно использовать в качестве
32-битного счётчика для повышения точности. Кроме того, он работает от напряжения 3,3 В,
что делает его совместимым с GPIO Raspberry Pi Pico.
На рис. 6.63 показана распиновка микросхемы.
Рис. 6.63: Распиновка микросхемы счетчика SN74LV8154.
● 182
Chapter 6 • Amateur Radio Hardware-based Projects
Описание выводов (A и B — две идентичные половинки счётчика):
Вход очистки
CCLR:
тактовой частоты по переднему фронту
CLKA, CLKB: Входы
Включение тактовой частоты B (активный LOW)
CLKBEN:
Нижний и старший байты затвора A
GAL, GAU:
Нижний и старший байты затвора B
GBL, GBU:
земля источника питания
GND:
Такт регистра (передний фронт сохраняет данные внутри)
RCLK:
Активный
LOW, когда счетчик A заполнен и готов к переполнению
RCOA:
источник
питания
Vcc:
Выходы
данных
(Y0 — младший значащий бит)
Y0-Y7:
Схема проекта показана на рис. 6.64. Схеме требуется тактовый импульс частотой 1 Гц для
входа RCLK. По переднему фронту RCLK значение 32-битного счётчика сохраняется внутри,
чтобы его можно было считать через выходы Y0–Y7 в 4 этапа. В этом проекте тактовые
импульсы частотой 1 Гц получаются с помощью GPS-приёмника (GPS Clickboard с сайта
www.mikroe.com) путём подключения к его выводу TP. Также возможно использовать
кварцевый резонатор с частотой 32 768 Гц и 15-каскадную схему двоичного счётчика, как
показано на рисунке 6.65. Эта схема состоит из 14-битного счётчика и D-триггера,
управляемого прямоугольным сигналом частотой 32 768 Гц.
Рис. 6.64: Принципиальная схема проекта.
● 183
Raspberry Pi Pico for Radio Amateurs
Рис. 6.65. 15-разрядный двоичный счётчик с кварцевым резонатором 32 768 Гц
На рис. 6.66 показан листинг программы (program:freq.py). Проект работает следующим
образом: на вход RCLK подаются импульсы каждую секунду, соответствующие импульсам,
полученным от GPS-приёмника (длительность импульсов составляет около 1 мс). Как только
обнаруживается передний фронт этого импульса, 32-битное значение считывается и
сохраняется в переменной Reading1. Следующее показание получается при поступлении
следующего импульса и сохраняется в переменной Reading2. Разница во времени между
двумя соседними импульсами составляет ровно одну секунду. Следовательно, разница между
двумя показаниями (т. е. переменная разность) — это количество отсчётов в секунду, то есть
частота сигнала. Разделив это значение на 1000, мы можем найти частоту в кГц.
Функция GetByte считывает 8 бит (байт) данных с выходов Y0–Y7 счётчика и
возвращает это значение в основную программу. Функция GetData считывает
32-битные данные, хранящиеся в микросхеме счётчика 74LV8154, активируя входы
GAL, GAU, GBL и GBU. Данные возвращаются в основную программу. Считывание
данных выполняется 4 раза.
#----------------------------------------------------------------#
ЧАСТОТОМЕР
#
============
#
# Это программа для частотомера. Частота
# отображается на ЖК-дисплее.
#
# Author: Dogan Ibrahim
# File
: freq.py.py
# Date
: Sept 2020
#------------------------------------------------------------------from machine import I2C, Pin
from pico_i2c_lcd import I2cLcd
import utime
g = [0]*4
y = [0]*8
● 184
Chapter 6 • Amateur Radio Hardware-based Projects
#
# Модуль ЖК-дисплея I2C, подключенный к SDA1, SCL1
#
i2c_lcd = I2C(id=1,scl=Pin(3),sda=Pin(2),freq=100000)
lcd = I2cLcd(i2c_lcd, 0x27, 2, 16)
ypins = [4, 5, 6, 7, 8, 9, 10, 11]
# Y0-Y7 pins
gpins = [12, 13, 14, 16]
# GA/GB pins
data = [0, 0, 0, 0]
disable = 1
enable = 0
pwrof32 = 2**32
for j in range(4):
g[j] = Pin(gpins[j], Pin.OUT)
# Установить как выходы
for j in range(8):
y[j] = Pin(ypins[j], Pin.IN)
# Установить как входы
RCLK = Pin(17, Pin.IN)
for j in range(4):
# Отключить все
g[j].value(disable)
#
# Считать байт данных из указанных 8 бит порта
#
def GetByte():
total = 0
k = 0
for j in range(8):
data = y[j].value()
data = data << k
total = total | data
k = k + 1
return total
#
# Получить 32-битные данные со счетчика
#
def GetData():
for j in range(4):
g[j].value(enable)
data[j] = GetByte()
g[j].value(disable)
● 185
Raspberry Pi Pico for Radio Amateurs
count = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24)
return count
lcd.move_to(0, 0)
lcd.putstr("Frequency Cntr")
while RCLK.value() == 1:
# ждать, если 1
pass
while RCLK.value() == 0:
# ждать, если 0
pass
Reading1 = GetData()
# читать Reading1
while RCLK.value() == 1:
pass
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr("Frequency (kHz):")
# Заголовок
while True: #Сделать навсегда
while RCLK.value() == 0:
#пока 0
pass
Reading2 = GetData()
# читать Reading2
while RCLK.value() == 1:
# пока 1
pass
difference = Reading2 - Reading1
# Рассчитать разницу
if difference < 0:
difference = difference + pwrof32
frequency = difference / 1000
# Частота (кГц)
frequency = str(frequency)[:12]
# В виде строки
lcd.move_to(0, 1)
lcd.putstr("
")
lcd.move_to(0, 1)
lcd.putstr(frequency)
# Отображать
Reading1 = Reading2
.
Рисунок 6.66: Программа: freq.py
При больших входных сигналах на входе можно использовать резистивный делитель
напряжения. Также на входе схемы можно использовать двоичные делители напряжения для
расширения частотного диапазона измерителя. Например, использование 4-разрядного
двоичного делителя позволяет расширить рабочий диапазон измерителя в 16 раз
(необходимо убедиться, что используемые компоненты могут работать на выбранных более
высоких частотах).
● 186
Chapter 6 • Amateur Radio Hardware-based Projects
Проект был собран на макетной плате. На рис. 6.67 показан пример вывода программы на
ЖК-дисплей. В данном примере входная частота составляла 300 кГц.
Рис. 6.67: Пример выходных данных.
6.9 Вольтметр – Амперметр – Омметр – Измеритель ёмкости
Большинство датчиков являются аналоговыми и выдают аналоговые выходные
напряжения или токи, пропорциональные измеряемой величине. Такие датчики
невозможно напрямую подключить к цифровым компьютерам без использования АЦП. В
этой главе мы рассмотрим использование каналов АЦП Raspberry Pi Pico.
Большинство АЦП общего назначения имеют разрядность 8 или 10 бит, хотя некоторые
профессиональные АЦП более высокого класса имеют разрядность 16 или даже 32 бита.
Время преобразования АЦП — одна из его важных характеристик. Это время, необходимое
АЦП для преобразования аналогового входного сигнала в цифровой. Чем меньше время
преобразования, тем лучше. Некоторые более дешёвые АЦП выдают преобразованные
цифровые данные в последовательном формате, в то время как более дорогие
профессиональные АЦП обеспечивают параллельный цифровой выход.
Raspberry Pi Pico имеет 5 каналов АЦП, 4 из которых расположены на выводах GP26, GP27,
GP28 и GP29 и известны как аналоговые каналы 0, 1, 2 и 3. Первые 3 канала доступны на
выводах GPIO, а четвёртый может использоваться для измерения напряжения VSYS платы.
Также имеется встроенный канал 4 АЦП, подключенный к датчику температуры.
АЦП Pico имеет разрешение 12 бит, преобразуя аналоговое входное напряжение в 4096 (от 0
до 4095) дискретных уровней. MicroPython же преобразует выходной сигнал в 16-битное число
в диапазоне от 0 до 65535.
Опорное напряжение АЦП, используемого в Pico, составляет +3,3 В. При использовании
такого АЦП разрешение составляет 3300 мВ / 65535 = 0,050 мВ на бит, или 50 мкВ/бит.
Следовательно, аналоговое входное напряжение 0,050 мВ дает цифровой выход 00000000
0000001, 0,1 мВ дает 0000000000000010 и так далее.
● 187
Raspberry Pi Pico for Radio Amateurs
6.9.1 Проект 15: Вольтметр
В этом проекте мы разработаем вольтметр для измерения аналоговых напряжений и отображения
результатов на ЖК-дисплее.
На рис. 6.68 показана принципиальная схема проекта. Измеряемое напряжение подается
на вход АЦП GP26 (A0, вывод 31) Raspberry Pi Pico.
Рис. 6.68: Принципиальная схема проекта.
На рис. 6.69 показан листинг программы (программа:Voltmeter.py) вместе с
примером выходных данных. Аналоговое входное напряжение считывается
с канала 0, преобразуется в милливольты и отображается на экране Thonny.
Рис. 6.69: Листинг программы и примеры выходных данных.
● 188
Chapter 6 • Amateur Radio Hardware-based Projects
Важно отметить, что максимальное входное напряжение не должно превышать
+3,3 В. Если требуется измерять более высокие напряжения, следует использовать
схему резистивного делителя напряжения для снижения входного напряжения.
См. рис. 6.70, где используются резисторы сопротивлением 10 кОм и 100 кОм. При
использовании этой схемы входное напряжение будет ослаблено в 0,909 раза.
Поэтому необходимо умножить результат на 11, как показано ниже:
mV = adc * 3300.0 * 11.0 / 1023.0
Рис. 6.70: Схема делителя напряжения.
Отображение величины напряжения на ЖК-дисплее
Программу на рис. 6.70 легко модифицировать для отображения измеренного напряжения на
ЖК-дисплее. На рис. 6.71 показана принципиальная схема, в которой используется
ЖК-дисплей, совместимый с I2C. Листинг программы (program:Voltmeter2) представлен
на рис. 6.72.
Рис. 6.71: Принципиальная схема.
#-------------------------------------------------------# VOLTMETER
# =========
#
# Это проект вольтметра. Измеряемое напряжение
# подается на GP26 (контакт 31) Pico
● 189
Raspberry Pi Pico for Radio Amateurs
# Эта версия программы отображает измеренное напряжение
# на ЖК-дисплее I2C
#
# Author: Dogan Ibrahim
# File
: Voltmeter2.py
# Date
: Sept 2021
#---------------------------------------------------------from machine import I2C, ADC, Pin
import utime
from pico_i2c_lcd import I2cLcd
#
# Модуль ЖК-дисплея I2C подключен к SDA1, SCL1
#
i2c_lcd = I2C(id=1,scl=Pin(3),sda=Pin(2),freq=100000)
lcd = I2cLcd(i2c_lcd, 0x27, 2, 16)
AnalogIn = ADC(0)
Conv = 3300 / 65535
while True:
mV = AnalogIn.read_u16()
mV = mV * Conv
lcd.clear()
mVstr = str(mV)[:7]
lcd.putstr(mVstr)
utime.sleep(1)
# Канал АЦП 0
# Коэффициент преобразования
# Выполнять бесконечно
# Считывать входные данные
# Ввод в мВ
# Очистить экран
# Преобразовать в строку
# Отобразить на экране
# Подождать 1 секунду
Рис. 6.72: Листинг программы.
6.9.2 Проект 16: Амперметр
Спроектировать амперметр легко, имея вольтметр. Проще всего использовать постоянный
резистор с известным сопротивлением, включенный последовательно с цепью, в которой
будет измеряться ток. Измеряя напряжение на этом резисторе, мы можем рассчитать ток,
протекающий по цепи, разделив напряжение на сопротивление.
Предположив, что максимальный ток, который мы хотим измерить в любой момент времени,
составляет 1 А, мы можем выбрать постоянный резистор сопротивлением 10 Ом и измерить
напряжение на этом резисторе. Максимальное напряжение составит 10 В. Необходимо
убедиться, что номинальная мощность резистора составляет не менее 20 Вт, поэтому, скорее
всего, он будет проволочным.
6.9.3 Проект 17: Омметр
Спроектировать омметр легко. Всё, что нам нужно, — это постоянный резистор, подключенный
последовательно с неизвестным резистором. Измеряя напряжение на неизвестном резисторе,
мы можем легко рассчитать его сопротивление. Сопротивление неизвестного резистора
отображается на ЖК-дисплее.
● 190
Chapter 6 • Amateur Radio Hardware-based Projects
Схема показана на рис. 6.73. Напряжение на неизвестном резисторе Rx определяется
следующим образом:
Vo = Vin × Rx / (R1 × Rx)
Или же значение неизвестного резистора Rx определяется следующим образом:
Rx = Vo × R1 / (Vin – Vo)
Однако, Vin 3,3 В. Если мы выберем R1 равным 3,3 кОм, то неизвестное сопротивление Rx
будет рассчитано по формуле:
Rx = Vo × 3300 / (3300 mV – Vo)
Где Rx измеряется в омах, а Vo — в милливольтах.
Рис. 6.73: Схема проекта.
На рис. 6.74 показан листинг программы (Программа: resistance.py). В начале
программы параметры АЦП и ЖК-дисплея инициализируются, как и в предыдущем
проекте. Затем программа вычисляет и отображает Rx на ЖК-дисплее, используя
приведенную выше формулу.
#-------------------------------------------------------# ОММЕТР
# =======
#
# Это проект омметра. Неизвестный резистор
# соединен последовательно с известным резистором в качестве делителя напряжения
# и его значение вычисляется и отображается
# на LCD
● 191
Raspberry Pi Pico for Radio Amateurs
#
# Author: Dogan Ibrahim
# File
: resistance.py
# Date
: Sept 2021
#---------------------------------------------------------from machine import I2C, ADC, Pin
import utime
from pico_i2c_lcd import I2cLcd
#
# Модуль ЖК-дисплея I2C подключен к SDA1, SCL1
#
i2c_lcd = I2C(id=1,scl=Pin(3),sda=Pin(2),freq=100000)
lcd = I2cLcd(i2c_lcd, 0x27, 2, 16)
AnalogIn = ADC(0)
# Канал АЦП 0
Conv = 3300 / 65535
# Коэффициент преобразования
R1 = 3300
# 3,3 кОм
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr("Resistance (Ohm)")
while True:
# Выполнять бесконечно
mV = AnalogIn.read_u16()
# Считывать входной сигнал
mV = mV * Conv
# Входной сигнал в мВ
Rx = mV * R1 / (3300 - mV)
Rx = str(Rx)[:6]
lcd.move_to(0, 1)
lcd.putstr(Rx)
# Отображать на дисплее
utime.sleep(1)
# Подождать 1 секунду
lcd.move_to(0, 1)
lcd.putstr("
")
lcd.move_to(0, 1)
Рис. 6.74: Программа: resistance.py.
6.9.4 Проект 18: Измеритель емкости
Это простой проект измерителя емкости, который позволяет достаточно точно измерять емкости в
диапазоне микрофарад. Схема основана на зарядке конденсатора через фиксированный резистор,
а значение емкости определяется путем нахождения постоянной времени цепи. Значение емкости
отображается на ЖК-дисплее.
На рис. 6.75 показана блок-схема схемы.
● 192
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.75: Блок-схема проекта.
Схема цепи показана на рис. 6.76. Резистор 10 кОм, соединенный последовательно с
неизвестным конденсатором, снова последовательно подключен к GP16 Raspberry Pi Pico.
АЦП и ЖК-дисплей подключены так же, как и в предыдущем проекте.
Рис. 6.76: Схема проекта.
На резистор подается напряжение +3,3 В для зарядки конденсатора. Постоянная времени
цепи определяется формулой T=RC. За это время напряжение на конденсаторе достигает
63,2% от своего конечного значения. Вычислив постоянную времени и разделив ее на
значение резистора, мы можем найти значение неизвестного резистора.
На рис. 6.77 показан листинг программы (program:capacitance.py). В начале программы
параметры ЖК-дисплея и АЦП инициализируются, как и в предыдущей программе. Внутри
цикла программы на вывод GP16 подается логическая единица (+3,3 В) для зарядки
неизвестного конденсатора через резистор 10 кОм. Затем программа считывает время
внутренних часов и сохраняет его в переменной StartTime, и непрерывно считывает
напряжение на конденсаторе, пока оно не достигнет 63,2% от +3,3 В. Поскольку значение
полного диапазона АЦП равно 65535, 63,2% соответствует 41418 (целое число), и это число
используется при считывании аналогового входа. Когда напряжение на конденсаторе
достигает 63,2% от своего конечного значения, время считывается и сохраняется в
переменной EndTime. Разница между EndTime и StartTime — это прошедшее время, которое
переводится в секунды. Это время, необходимое для зарядки конденсатора до его постоянной
времени. Разделив это время на значение резистора, получаем значение неизвестного
конденсатора в фарадах. Затем это значение переводится в микрофарады и отображается на
экране.
● 193
Raspberry Pi Pico for Radio Amateurs
#-------------------------------------------------------# ИЗМЕРИТЕЛЬ ЕМКОСТИ
# ====================
#
# Это проект измерителя емкости. Неизвестный конденсатор
# подключается последовательно с известным резистором,
# вычисляется постоянная времени цепи,
# затем вычисляется емкость и отображается на ЖК-дисплее.
#
# Author: Dogan Ibrahim
# File
: capacitance.py
# Date
: Sept 2021
#---------------------------------------------------------from machine import I2C, ADC, Pin
import utime
import time
from pico_i2c_lcd import I2cLcd
#
# Модуль ЖК-дисплея с интерфейсом I2C подключен к контактам SDA1 и SCL1.
#
i2c_lcd = I2C(id=1,scl=Pin(3),sda=Pin(2),freq=100000)
lcd = I2cLcd(i2c_lcd, 0x27, 2, 16)
AnalogIn = ADC(0)
# Канал АЦП 0
resistor = 10000
# Резистор 10 кОм
charge = Pin(16, Pin.OUT)
# GP16, pin 21
charge.value(0)
# изначально при 0
def GetADCData():
mV = AnalogIn.read_u16()
return mV
while GetADCData() > 100:
pass
while True: # Делай это вечно
lcd.move_to(0, 0)
lcd.putstr("Measured (uF):")
# Заголовок
charge.value(1)
# Начало зарядки
StartTime = utime.ticks_us()
# Время начала
while GetADCData() < 41418:
# Постоянная времени
pass
EndTime = utime.ticks_us()
● 194
# Конец времени
Chapter 6 • Amateur Radio Hardware-based Projects
ElapsedTime = utime.ticks_diff(EndTime, StartTime)
ElapsedTime = ElapsedTime / 1000000
uF = (ElapsedTime / resistor) * 1000000
mF = str(uF)[:7]
lcd.move_to(0, 1)
lcd.putstr(mF)
charge.value(0)
while GetADCData() > 100:
pass
time.sleep(1)
lcd.clear()
Рис. 6.77: Программа:capacitance.py.
Рис. 6.78 показывает пример отображения.
Рис. 6.78: Пример отображения.
При использовании зарядного резистора сопротивлением 10 кОм постоянные
времени для различных значений емкости конденсаторов следующие:
Capacitor
0.001 μF
0.01 μF
0.1 μF
1 μF
10 μF
100 μF
1000 μF
Time constant
0.01 ms
0.1 ms
1 ms
10 ms
100 ms
1s
10 s
Более точные результаты при работе с небольшими конденсаторами можно получить,
увеличив значение резистора. Это связано с тем, что точность синхронизации
Raspberry Pi Pico на уровне микросекунд не идеальна. Увеличение значения резистора
приведет к увеличению времени зарядки конденсатора. Например, для измерения
емкости конденсатора в 100 мкФ потребуется около 2 минут:
● 195
Raspberry Pi Pico for Radio Amateurs
Capacitor
0.001 μF
0.01 μF
0.1 μF
1 μF
10 μF
100 μF
Time constant
1 ms
10 ms
100 ms
1s
10 s
100 s
Читателям может быть интересно узнать, что на рынке доступны профессиональные и
недорогие LCR-метры. Одним из таких примеров является измеритель сопротивления,
емкости и индуктивности Atlas LCR40 от Peak Electronic Design Ltd. (рис. 6.79). Этот прибор
имеет следующие диапазоны измерения:
• сопротивление: от 1 Ом до 2 мегаом
• емкость: от 0,5 пФ до 10 000 мкФ
• индуктивность: от 1 мкГн до 10 Гн
Рис. 6.79: Электронный LCR-метр.
6.10 Проект 19: Измеритель мощности ВЧ
Данный проект представляет собой программируемый измеритель мощности
радиочастотного сигнала, использующий плату RF Meter Clickboard (www.mikroe.com),
который позволяет измерять мощность радиочастотного сигнала в диапазоне от 1 МГц до 8
ГГц в пределах 60 дБ (приблизительно). Диапазон входной мощности составляет от –60 дБ
до примерно 0 дБ. Таким образом, с помощью этого измерителя можно измерять мощность в
милливаттах (мВт). Для измерения более высоких мощностей потребуется использовать
модули аттенюатора мощности радиочастотного сигнала.
Предусмотрен антенный разъем для подключения передатчика, выходная мощность которого
должна быть измерена. Сигнал обрабатывается логарифмическим детектором AD8318 от
Analog Devic-es. Полученное напряжение подается на АЦП MCP3201, который отображает
мощность в дБм. В этом проекте мощность отображается на ЖК-дисплее.
● 196
Chapter 6 • Amateur Radio Hardware-based Projects
Измерительный прибор RF Meter Click (рисунок 6.80) работает с тремя сигналами: CS, Data и Clock.
Рис. 6.80: Плата «ВЧ-измеритель Click».
На рис. 6.81 показана принципиальная схема радиочастотного измерителя Click. Разъем
антенны расположен в верхнем левом углу рисунка, рядом с ним находится микросхема
логарифмического детектора AD8313 и АЦП MCP3201. На разъеме mikroBUS, показанном в
верхнем правом углу рисунка, используются следующие контакты (NC = Нет соединения).
RF Meter pin
Function
1
Analog output
2 NC
3 CS
4 Clock
5 Data
6 NC
7
+3.3 V
8 GND
9 GND
10
+5 V
11 NC
12 NC
13 NC
14 NC
15 NC
16 NC
● 197
Raspberry Pi Pico for Radio Amateurs
Рис. 6.81: Схема подключения ВЧ-измерителя.
Рис. 6.82. блок-схема проекта.
Рис. 6.82: Блок-схема проекта.
Схема проекта показана на рис. 6.83. Контакты Clock и Data радиочастотного измерителя
подключены к выводам GP6 (вывод 9) и GP7 (вывод 10) Raspberry Pi. Вывод CS подключен к
выводу GP8 (вывод 11). ЖК-дисплей I2C подключен так же, как и в предыдущих проектах на
основе ЖК-дисплея, где его выводы SDA и SCL подключены к выводам SDA1 (GP2) и SCL1
(GP3) Raspberry Pi Pico соответственно.
● 198
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.83: Схема проекта.
Прежде чем перейти к подробностям программы, стоит кратко рассмотреть работу микросхем
AD8318 и MCP3201.
AD8318
AD8318 — это усилитель с логарифмическим демодулятором, способный преобразовывать
входной радиочастотный сигнал в соответствующее выходное напряжение в децибелах.
Микросхема обеспечивает точный выходной сигнал для сигналов от 1 МГц до 6 ГГц и может
использоваться для работы до 8 ГГц. Логарифмический наклон микросхемы составляет
номинально –25 мВ/дБ, но при необходимости может быть отрегулирован. Основные
характеристики AD8318:
•
•
•
•
•
•
Работа в диапазоне частот от 1 МГц до 8 ГГц
5 V питания
Динамический диапазон 60 дБ (от –60 дБ до 0 дБ)
Низкий уровень шума на выходе
Встроенный датчик температуры
Точность ±1,0 дБ в диапазоне 55 дБ (для частот < 5,8 ГГц)
На рис. 6.84 показана логарифмическая зависимость отклика AD8318.
● 199
Raspberry Pi Pico for Radio Amateurs
Рис. 6.84: Логарифмическая характеристика AD8318 (Analog Devices).
Как видно из рис. 6.84, наклон кривой составляет 25 мВ/дБ, а точка пересечения оси Pin
находится на уровне 20 дБ. Следовательно, соотношение вход-выход определяется
(относительно 50 Ом):
Pin = 20 – 40Vo
где,
Pin — входная мощность в dBm, а Vo — выходное напряжение в вольтах. Мы будем
использовать приведенное выше уравнение для расчета мощности ВЧ-сигнала на основе
измерения напряжения на выходе AD8318. Напряжение будет измеряться с помощью
встроенного АЦП MCP3201.
Поскольку наклон и точка пересечения немного различаются от устройства к устройству, для
обеспечения высокой точности рекомендуется калибровка микросхемы. Калибровку
микросхемы можно выполнить, подав на вход микросхемы два неизвестных уровня сигнала и
измерив соответствующие выходные напряжения. Наклон и точка пересечения затем
определяются по формулам:
Slope = (Vout1 – Vout2) / (Pin1 – Pin2)
and
Intercept = Pin1 – Vout1 / Slope
После определения наклона и точки пересечения соотношение между входом и выходом
можно записать как:
Pin = Intercept + Vout / Slope
● 200
Chapter 6 • Amateur Radio Hardware-based Projects
На входной цепи подключен внешний шунтирующий резистор 52,3 Ом для обеспечения
адекватного широкополосного согласования 50 Ом, поэтому нет необходимости в реактивном
согласовании входной цепи.
MCP3201
Это 12-разрядный АЦП со следующими основными характеристиками:
•
•
•
•
•
•
рабочее напряжение от 2,7 до 5,5 В
интерфейс SPI для подключения к хосту
встроенная функция выборки и удержания
частота дискретизации 100 ksps (при 5 В)
частота дискретизации 50 ksps (при 2,7 В)
активный ток 400 мкА (при 5 В)
Опорное напряжение АЦП на плате RF Meter Click установлено на +2,5 В. АЦП подключен к
выходу AD8318 и считывает аналоговый сигнал, преобразуя его в цифровой. Выходное
напряжение считывается Raspberry Pi Pico, преобразуется в дБм и отображается на
ЖК-дисплее.
На рис. 6.85 показан листинг программы (program:rfmeter.py). В начале программы
импортируются используемые библиотеки. Определены соединения между Raspberry Pi Pico и
платой RF Meter Click. Тактовый сигнал и CS настроены как выходы, а данные — как вход.
Основной цикл программы вызывает функцию GetADCData для считывания аналогового
выходного напряжения платы RF Meter Click. Поскольку опорное напряжение АЦП составляет
2,5 В, и это 12-битный преобразователь, цифровое показание АЦП умножается на 2,5 / 4096
для преобразования в вольты. Затем вычисляется мощность в dBm и отображается на
ЖК-дисплее каждую секунду.
#----------------------------------------------------------------#
RF МЕТР
#
========
#
# Это программа для измерения радиочастотного сигнала, которая отображает
# его мощность на ЖК-дисплее.
# Author: Dogan Ibrahim
# File
: rfmeter.py
# Date
: August 2021
#------------------------------------------------------------------from machine import I2C, Pin
from pico_i2c_lcd import I2cLcd
import utime
#
# Модуль ЖК-дисплея с интерфейсом I2C подключен к контактам SDA1 и SCL1.
#
i2c_lcd = I2C(id=1,scl=Pin(3),sda=Pin(2),freq=100000)
● 201
Raspberry Pi Pico for Radio Amateurs
lcd = I2cLcd(i2c_lcd, 0x27, 2, 16)
CS = Pin(8, Pin.OUT)
# CS pin
DOUT = Pin(7, Pin.IN)
# Data pin
CLK = Pin(6, Pin.OUT)
# CLK pin
#
# This function returns the ADC data read from the MCP3201
#
def GetADCData():
Data = 0
CS.value(1)
# CS=1
CLK.value(1)
# CLK=1
CS.value(0)
# CS=0
m = 14
while m >= 0:
CLK.value(0)
Dat = DOUT.value()
CLK.value(1)
Dat = Dat << m
Data |= Dat
m = m - 1
CS.value(1)
Data &= 0xFFF
return Data
lcd.move_to(0, 0)
# Cursor at (0,0)
lcd.putstr("RF Power (dBm):")
# Заголовок
#
# Считывание аналоговых данных, расчет мощности и отображение результатов на ЖК-дисплее.
#
while True:
adc = GetADCData()
# Считывание АЦП
V = adc * 2.5 / 4096.0
# В вольты
power = 20.0 - 40.0 * V
# Мощность
powerstr = str(power)[:7]
# В строку
lcd.move_to(0, 1)
# Курсор в точке (0,1)
lcd.putstr("
")
lcd.move_to(0, 1)
lcd.putstr(powerstr)
utime.sleep(1)
# Очистка
# Курсор в точке (0,1)
# Отображение мощности
# подождать 1 секунду
Рис. 6.85: Программа: rfmeter.py.
● 202
Chapter 6 • Amateur Radio Hardware-based Projects
На рис. 6.86 показан пример вывода на ЖК-дисплей. Проект был собран на макетной плате и
показан на рис. 6.87.
Рис. 6.86: Пример выходных данных.
Рис. 6.87: Проект, собранный на макетной плате.
6.10.1 ВЧ аттенюаторы
Описанный в этом проекте ВЧ-измеритель может измерять значения от –65 дБм до нескольких
дБм. Поэтому для увеличения полезного диапазона на входе измерителя определенно
потребуется использовать модули ВЧ-аттенюаторов. ВЧ-аттенюаторы можно изготовить
самостоятельно или приобрести готовые у продавцов ВЧ-оборудования на Amazon.
На рис. 6.88 показаны некоторые типичные модули ВЧ-аттенюаторов на 30 дБ и 40 дБ.
Рис. 6.88: Модули радиочастотного аттенюатора.
● 203
Raspberry Pi Pico for Radio Amateurs
6.10.2 дБ, дБм и Вт?
Многие читатели могут путаться в терминах дБ, дБм и ватты. В этом разделе мы попытаемся
прояснить эти термины.
ДБ (децибел) — это логарифмическая шкала, используемая для измерения отношения двух
физических величин. Например, она используется для выражения коэффициента усиления по
напряжению или коэффициента усиления по мощности транзисторного усилителя.
Коэффициент усиления по напряжению — это отношение выходного напряжения к входному
напряжению. Аналогично, коэффициент усиления по мощности — это отношение выходной
мощности к входной мощности.
При выражении коэффициента усиления по напряжению мы используем формулу:
voltage gain = 20 log10 (Vo / Vi)
коэффициент усиления по напряжению = 20 log10(Vo/Vi) Где Vo и Vi — выходное и входное
напряжения усилителя соответственно. Например, если Vo/Vi = 100, это равно 40 дБ, так как
log10(100) = 2. Аналогично, если коэффициент усиления по напряжению выражен как 30 дБ, то
отношение Vo/Vi = 31,6, так как:
или
30 = 20 log10 (x)
30 / 20 = log10 (x)
1.5 = log10 (x)
x = 101.5 = 31.6
При выражении коэффициента усиления по мощности мы используем формулу:
Power gain = 10 log10(Po / Pi)
Коэффициент усиления по мощности = 10 log10(Po /Pi), где Po и Pi — выходная и входная
мощности усилителя соответственно. Например, если Po/Pi = 80, это равно 19 дБ, так как log10
(80) = 1,90.
ДБм используется для выражения уровня мощности (дБ) относительно одного милливатт
(мВт). В радиочастотной области он часто используется как мера абсолютной мощности,
поскольку он отсчитывается от ватта. дБ является безразмерной величиной, поскольку
представляет собой отношение двух величин. Хотя дБм также является безразмерной
величиной, это абсолютное измерение, поскольку оно сравнивается с фиксированной опорной
величиной.
В аудиотехнике дБм обычно отсчитывается от нагрузки 600 Ом, тогда как в радиочастотной
технике он в основном отсчитывается от нагрузки 50 Ом. В телевизионной технике дБм
обычно отсчитывается от нагрузки 75 Ом.
Связь между дБм и мощностью в мВт определяется формулой:
dBm = 10 Log10 (P / 1 mW)
где P измеряется в милливаттах. Например, если P = 1000 мВт, его эквивалентное
значение в дБм находится как: дБм = 10 log10(1000) = 30
dBm = 10 log10 (1000) = 30
● 204
Chapter 6 • Amateur Radio Hardware-based Projects
Зная значение в дБм, мы можем рассчитать мощность следующим образом:
P = 10x/10
Где x выражено в дБм, а P — в милливаттах.
На рис. 6.89 показан генератор напряжения и нагрузка. Зависимость напряжения на нагрузке
от её значения в дБм зависит от величины нагрузки следующим образом (при условии
синусоидального входного сигнала):
Для нагрузки 50 Ом (т.е. того, что нас интересует):
P = V2 / R
или
with P in watts, V in volts, R in ohms.
V2 = R × P
Принимая Pin за милливатты, мы можем записать:
V2 = R × 10x/10 × 10–3
or
где x измеряется в дБм, а vi — в вольтах среднеквадратичного значения. В качестве
примера, для подачи сигнала мощностью 10 дБм на нагрузку 50 Ом требуется
напряжение:
= 0.707 VRMS
Рис. 6.89: Напряжение на нагрузке.
В таблице 6.2 приведены значения в дБм, их эквивалентная мощность в ваттах (или мВт)
и напряжение (среднеквадратичное значение) для некоторых часто используемых
значений.
● 205
Raspberry Pi Pico for Radio Amateurs
dBm
W
V (RMS)
60
1000
223.6
57
501.2
158.3
53
199.5
99.88
50
100
70.71
47
50.12
50.06
44
25.12
35.44
43
19.95
31.59
40
10
22.36
37
5.01
15.83
33
2
10
30
1
7.07
25
316 mW
3.97
20
100 mW
2.23
15
31.6 mW
1.25
10
10 mW
707.1 mV
5
3.16 mW
397.6 mV
0
1 mW
223.6 mV
–10
0.1 mW
70.71 mV
–20
0.01 mW
22.36 mV
–30
0.001 mW
7.07 mV
–40
1 μW
2.23 mV
–50
0.01 μW
707 μV
–60
0.001 μW
223 μV
Таблица 6.2 дБм, ватты (Вт) и VRMS.
6.11 Проект 20: Использование платы RadioStation Click
Это проект маломощного программируемого FM-передатчика. В этом проекте мы будем
использовать небольшую плату RadioStation Click, производимую компанией mikroElektronika
(www.mikroe.om). На рис. 6.90 показана плата с разъемом для микрофона, контактом для
антенны и контактами управления.
RadioStation Click — это уникальная плата серии «click», которая может использоваться для
трансляции музыки в диапазоне УКВ FM-радиовещания при наличии лицензии. Она оснащена чипом
Si4713-B30 от Silicon Labs, лучшим в своем классе интегрированным стереопередатчиком
FM-вещания, работающим в диапазоне частот от 76 МГц до 108 МГц. Она также может передавать
данные RDS/RDBS. Эта плата Click может быть оснащена небольшой FM-антенной, которая
используется для расширения дальности вещания. Одним из преимуществ этого универсального
FM-передатчика является
● 206
Chapter 6 • Amateur Radio Hardware-based Projects
микросхема стереопередатчика, которая практически не требует внешних компонентов,
поэтому с ней довольно легко работать. Это делает её идеальным решением для
использования в сотовых телефонах, MP3-плеерах, портативных медиаплеерах,
беспроводных колонках, персональных компьютерах и любых других приложениях, где
требуется радиовещание на коротких расстояниях.
Микросхема Si4713-B30 выполняет частотную модуляцию (ЧМ) в цифровой области для
достижения высокой точности и оптимальной производительности. Встроенный DSP
обеспечивает регулировку модуляции и управление динамическим диапазоном сигнала для
наилучшего качества звучания. Аудиосигнал обрабатывается для достижения оптимальных
динамических качеств. Кроме того, Si4713 имеет программируемые индикаторы низкого и
высокого уровня звука, которые позволяют включать и выключать несущий сигнал в
зависимости от наличия аудиоконтента. Интегрированный DSP также отвечает за
стереофоническое кодирование MPX и ЧМ-модуляцию сигнала. Низкоуровневый цифровой
сигнал промежуточной частоты (ПЧ) затем фильтруется и поступает на выходной микшер, где
преобразуется в радиочастотный сигнал (РЧ). Дополнительно фильтруются гармоники и шумы
РЧ-сигнала для получения сигнала, соответствующего местным нормам по передаче
сверхнизкой мощности РЧ-сигнала (FCC, ETSI, ARIB…). РЧ-сигнал передается через
небольшую антенну. Устройство поддерживает все виды замкнутых/полюсных FM-антенн.
Рис. 6.90: Плата RadioStation Click.
Плата работает от напряжения +3,3 В и имеет следующую схему расположения контактов
(NC = Нет соединения):
Pin no
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Function
NC
RST
SEN
NC
C
NC
+3.3 V
GND
GND
NC
SDA
SCL
NC
NC
Description
Reset (LOW to reset)
Set I2C address
I2C data
I2C clock
● 207
Raspberry Pi Pico for Radio Amateurs
15
16
INT
NC
Interrupt pin
Плата RadioStation Click взаимодействует с главным компьютером через интерфейс I2C.
Вывод SEN используется для выбора адреса I2C. Когда CS находится в высоком состоянии,
7-битный адрес I2C равен 0x63. Когда SEN находится в низком состоянии, 7-битный адрес
равен 0x11.
Микросхема Si4713-B30 способна измерять принимаемый сигнал. Антенна, используемая для
передачи сигнала, также может использоваться для приема входящего сигнала,
передаваемого приемным устройством. Хотя она может использоваться как для приема, так и
для передачи сигнала, антенна не может работать в обоих режимах одновременно. Эта
функция может быть полезна при калибровке мощности передачи платы Click.
Перед использованием микросхемы Si4713-B30 стоит кратко ознакомиться с принципами её
работы. См. технические характеристики по ссылкам:
https://download.mikroe.com/documents/datasheets/Si4712-13-B30.pdf
и
www.silabs.com/documents/public/application-notes/AN332.pdf
Микросхема Si4713-B30 обладает следующими основными характеристиками:
•
•
•
•
•
•
•
поддержка диапазона 76-108 МГц
цифровой стереомодулятор
программируемая предварительная коррекция
аналоговый/цифровой аудиовход
кодировщик RDS/RBDS
программируемый уровень передачи
регулировка уровня звука
Микросхема Si4713 поддерживает стандартные европейский RDS и американский RBDS,
включая декодирование символов, блочную синхронизацию и коррекцию ошибок. Используя
эту функцию, вы можете передавать текст (например, имя исполнителя, воспроизводящего
песню и т. д.) на FM-приемник, совместимый с RDS/RBDS.
Выход TXO микросхемы напрямую подключается к антенне с одним внешним индуктором для
обеспечения гармонической фильтрации. Поддерживаются как цифровые, так и аналоговые
аудиовходы. Уровень аналогового стереофонического аудиовхода программируется и может
быть настроен программно. Пиковый уровень входного аудиосигнала по умолчанию установлен
на 636 мВ.
Предусмотрен цифровой регулятор динамического диапазона с программируемыми
параметрами усиления, порога, скорости атаки и скорости затухания. Эта функция может
использоваться для уменьшения динамического диапазона аудиосигнала, тем самым улучшая
качество звучания на FM-приемнике. Цифровой аудиолимитер предотвращает
перемодуляцию выходного сигнала передатчика, динамически ослабляя пики входного
аудиосигнала, превышающие программируемое пороговое значение.
● 208
Chapter 6 • Amateur Radio Hardware-based Projects
К передаваемому сигналу может быть применен программируемый фильтр
предварительной коррекции для усиления высоких звуковых частот и улучшения отношения
сигнал/шум. Приемники выполняют деэмфазирование для ослабления высоких частот и
восстановления ровной частотной характеристики. Стандартная европейская
предварительная коррекция составляет 50 мкс, в то время как в США и некоторых других
странах используется 75 мкс.
Помимо функции передатчика, Si4713 предоставляет три универсальных вывода GPIO для
подключения светодиодов и других устройств к микросхеме. Эти выводы недоступны с
платы RadioStation Click.
В таблице 6.3 приведен список доступных команд Si4713-B30 (см. техническое описание для
получения дополнительной информации). В дополнение к этим основным командам,
предоставляется большое количество команд свойств для программирования таких функций,
как предварительное усиление, уровень линейного входного сигнала, девиация звука,
девиация RDS, опорный тактовый сигнал, пороговые уровни звука, управление динамическим
диапазоном звука и т. д.
Таблица 6.3: Команды Si4713-B30.
В рамках нашего проекта нас интересуют только следующие команды:
0x30
0x31
настроиться на заданную частоту передачи
TX_TUNE_FREQ
TX_TUNE_POWER установить уровень выходной мощности и настроить
конденсатор антенны
На рис. 6.91 представлена блок-схема проекта.
● 209
Raspberry Pi Pico for Radio Amateurs
Рис. 6.91: Блок-схема проекта.
На рис. 6.92 показана принципиальная схема платы RadioStation Click. Аудиовход и антенный
разъем расположены слева на рисунке. 16-контактный разъем mikroBUS находится в правом
верхнем углу рисунка.
Рис. 6.92: Плата RadioStation Click (www.mikroe.com).
Схема проекта показана на рис. 6.93. Адрес I2C устанавливается равным 0x11 путем
подключения контакта CS к GND. Контакты I2C SDA1 и SCL1 подключены к контактам SDA1
(GP2, контакт 4) и SCL1 (GP3, контакт 5) Raspberry PiPico соответственно.
● 210
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.93: Схема проекта.
Работа программы
Работа программы показана на рис. 6.94 в виде PDL (ProgramDescriptionLanguage),
представляющего собой описание алгоритма программы в свободном формате.
MAIN:BEGIN
Display "RADIO STATION"
Call Reset to reset the chip
Call SendCommand to set to operate analog with crystal reference clock
Call SetProperty to set pre-emphasis to 50μs
Read required operating frequency from user
Read required TX power from user
Call SendCommand to set required operating frequency
Call SendCommand to set required TX power
Get operating frequency
Display operating frequency
Exit if Cntrl+C detected
MAINEND
Reset:BEGIN
Ser RST HIGH
Wait 0.5 second
Set RST LOW
Wait 0.5 second
Set RST HIGH
Wait 0.5 second
Reset:END
SendCommand:BEGIN
Get the command type (first byte)
Get the command arguments (remaining bytes)
● 211
Raspberry Pi Pico for Radio Amateurs
Send command with arguments to the chip
Get response from the chip
IF error in response THEN
Display error message
Exit program
ENDIF
SendCommand:END
SetProperty:BEGIN
Extract upper and lower bytes of the property
Extract the upper and lower bytes of the data
Call SendCommand to send the property to the chip
SetProperty:END
RcvTuneStatus:BEGIN
Send command to get the Tune Status
Return the upper and lower frequency bytes
RcvTuneStatus:END
PowerOff:BEGIN
Clear RST
PowerOff:END
Рис. 6.94: PDL программы.
На рис. 6.95 показан листинг программы (program:station.py). В начале программы
импортируются необходимые модули. Контакт 'RST' назначается микросхеме GP16 и
настраивается как выход. Затем определяются команды и свойства, используемые в
программе.
Основной программный цикл начинается с отображения заголовка «РАДИОСТАНЦИЯ». Затем
микросхема перезагружается путем вызова функции Reset, и предварительная коррекция
устанавливается на 50 мкс. Пользователю предлагается ввести требуемую рабочую частоту.
Частота должна быть введена в диапазоне от 76 до 108 МГц, без двоеточия и с указанием
частоты в кГц. Она должна быть в единицах 10 кГц с шагом 50 кГц. Например, 7605 (т.е. 76,05
МГц) является допустимым значением, но 7601 (т.е. 76,01 МГц) не является допустимым
значением, поскольку это не шаг 50 кГц. Ниже приведены некоторые примеры:
97 MHz
97.5 MHz
106 MHz
106.5 MHz
enter: 9700
enter: 9750
enter as: 10600
enter as: 10650
Затем пользователю предлагается ввести требуемую мощность передачи в дБмкВ в диапазоне
от 88 до 115. Передача начинается после установки частоты и мощности. Затем
программа получает требуемую рабочую частоту и отображает ее в качестве подтверждения.
● 212
Chapter 6 • Amateur Radio Hardware-based Projects
Передача завершается вводом символа X. Обратите внимание, что остановка программы
другими способами не приводит к завершению передачи.
#----------------------------------------------------------------РАДИОСТАНЦИЯ
==============
#
#
#
# Эта программа использует плату RadiOStation Click для проектирования
# системы радиостанции (примечание: передача на
# частотах FM-радиовещания запрещена)
#
# Author: Dogan Ibrahim
# File
: station.py
# Date
: August 2021
#------------------------------------------------------------------from machine import I2C, Pin
import utime
#
# Модуль I2C подключен к SDA1, SCL1
#
i2c = machine.I2C(1, scl=Pin(3), sda=Pin(2), freq=100000)
print("i2c address (hex) = ", i2c.scan())
address = 0x11
# адрес
RST = Pin(16, Pin.OUT)
# RST — это выходной сигнал.
#
# Параметры микросхемы, используемые в программе.
#
POWER_UP = 0x01
SET_PROPERTY = 0x12
TX_TUNE_FREQ = 0x30
TX_TUNE_POWER = 0x31
TX_TUNE_STATUS = 0x33
TX_PREEMPHASIS = 0x2106
#
# Перед началом использования сбросьте настройки чипа.
#
def Reset():
RST.value(1)
utime.sleep(0.5)
RST.value(0)
utime.sleep(0.5)
RST.value(1)
● 213
Raspberry Pi Pico for Radio Amateurs
buff =[0]*10
#
# Эта функция отправляет команду микросхеме. Команда — это
# первый байт, аргументы — это оставшиеся байты.
#
def SendCommand(BytesInput, ByteResponse):
buff[0] = BytesInput[0]
for i in range(1, len(BytesInput)):
buff[i] = BytesInput[i]
i2c.writeto(address, bytearray(buff))
# Отправить на чип
utime.sleep(0.2)
# Подождать 0,2 с
# Получить ответ
res = i2c.readfrom(address, 1)
if res[0] != ByteResponse:
# Error?
print("Error in command response:")
# Отобразить Error
print("Response code = %d" %hex(res[0]))
# Отобразить код
exit(0)
# Выход
#
# Эта функция устанавливает требуемое свойство. Верхняя и
# нижняя части свойства и данных извлекаются и отправляются на микросхему.
#
def SetProperty(ReqProperty, Data):
p1 = ReqProperty >> 8
# Верхний байт
p2 = ReqProperty & 0xFF
# Нижний байт
# Верхний байт
# Нижний байт
p3 = Data >> 8
p4 = Data & 0xFF
SendCommand([SET_PROPERTY,0, p1, p2, p3, p4], 0x80)
#
# Эта функция возвращает программе состояние TUNE. Верхнее
# и нижнее значения рабочей частоты возвращаются в
# основную программу. Бит CTS устанавливается, когда
# безопасно отправить следующую команду.
#
def RcvTuneStatus():
buff[0] = TX_TUNE_STATUS
buff[1] = 0x01;
i2c.writeto(address, bytearray(buff))
res = i2c.readfrom(address, 8)
return(res[2], res[3])
#
# Эта функция выключает станцию и прекращает передачу.
● 214
Chapter 6 • Amateur Radio Hardware-based Projects
#
def PowerOff():
RST.value(0)
#
# Начало ОСНОВНОЙ программы
#
print("")
print("RADIO STATION")
# Отобразить заголовок
print("=============")
# Сброс микросхемы
Reset()
SendCommand([POWER_UP, 0x12, 0x50], 0x80)
# Использование кварца, устан. аналог сигнала
utime.sleep(1)
# Ожидание 1 с
SetProperty(TX_PREEMPHASIS, 1)
# Стандартное время 50 мкс
freq = int(input("Enter frequency (7600-10800): "))
TXPower = int(input("Enter TX power (88dBuV-115dBuV): "))
print("Wait...")
print("")
SendCommand([TX_TUNE_FREQ, 0, freq >>8, freq & 0xFF], 0x80)
utime.sleep(5)
fh,fl=RcvTuneStatus()
utime.sleep(5)
SendCommand([TX_TUNE_POWER, 0, 0, TXPower, 0], 0x80)
utime.sleep(2)
print("End of setup...")
fh, fl = RcvTuneStatus()
setfreq = fh*256 + fl
print("")
print("Transmitting on: %d" %(setfreq))
# Отображение частоты
print("")
i="a"
while i != "X":
i = input("Enter X to exit: ")
if i == "X":
PowerOff()
print("")
print("END OF TRANSMISSION")
Рис. 6.95: Программа: station.py.
● 215
Raspberry Pi Pico for Radio Amateurs
На рис. 6.96 показан пример запуска программы, где рабочая частота и мощность передатчика
были выбраны равными 106 МГц и 95 дБмкВ соответственно.
Рис. 6.96: Пример запуска программы.
Проект был собран на макетной плате, как показано на рис. 6.97.
Рис. 6.97: Проект, собранный на макетной плате.
Возможно, вам захочется поэкспериментировать с включением функциональности
RDS/RBDS в программу.
● 216
Chapter 6 • Amateur Radio Hardware-based Projects
Примечание: передача в любом диапазоне вещания и создание радиостанции без лицензии
запрещены. Данный проект предоставляется исключительно в образовательных целях, и ни
автор, ни издатели не несут ответственности за его использование или его часть.
6.12 Упражнения по азбуке Морзе
Азбука Морзе — один из старейших, но широко используемых средств связи для
радиолюбителей. В этом разделе представлены несколько проектов по тренировке навыков
работы с азбукой Морзе.
6.12.1 Проект 21: Символы, вводимые пользователем
В этом проекте мы разработаем тренажер для отработки навыков азбуки Морзе, в котором текст из
букв, введенный пользователем, отправляется на зуммер, подключенный к Raspberry Pi Pico.
Время (т.е. скорость) передачи кода может быть установлено пользователем с помощью
клавиатуры ПК.
Приведенная здесь информация может быть не новой для некоторых читателей, но
она приведена для полноты.
Скорость передачи азбуки Морзе определяется следующим образом:
•
•
•
•
•
Dit: 1 единица
Dah: 3 единицы
расстояние между символами «дит» и «дах»: 1 единица
расстояние между символами слова: 3 единицы
расстояние между словами: 7 единиц
Скорость передачи азбуки Морзе определяется количеством слов в минуту, которые можно
передать или принять. На большинстве экзаменов для радиолюбителей от кандидатов ожидается
передача и прием не менее 12 слов в минуту.
В качестве стандартного слова при расчете скорости используется слово PARIS. Это слово
состоит из 50 единиц времени:
P:
A:
R:
I:
S:
.--.
..-.
..
…
1
1
1
1
1
1
1
1
1
1
3
3
3
1
1
1 3 1 1 (3)
(3)
1 1 (3)
(3)
1 1 [7]
14 units
8 units
10 units
6 units
12 units
Где () — время между символами, а [] — время между словами. Обратите внимание, что в
конце символа мы не вставляем время точки, а вставляем время между символами (3
единицы). Аналогично, в конце слова мы не вставляем время точки, а вставляем время
между словами (7 единиц).
Всего единиц = 50
● 217
Raspberry Pi Pico for Radio Amateurs
Формула для количества слов в минуту может быть рассчитана следующим образом:
wpm = слов в минуту.
\
Если принять за стандарт 50 слов в минуту (количество символов в минуту), то:
Секунды на символ, spd = 60 / (50 wpm), или spd = 1,2 / wpm.
Мы можем указать это в миллисекундах:
Миллисекунды на дин, mpd = 60000 / (50 wpm) = 1200 / wpm.
Таким образом, зная требуемое количество слов в минуту, мы можем рассчитать
время каждого дита в миллисекундах следующим образом:
mpd = 1200 / wpm
Например, если требуемое количество слов в минуту равно 12, то
mpd = 1200 / 12 = 100 миллисекунд.
То есть, мы должны учитывать 100 мс в качестве основной единицы измерения времени.
Аналогично, если требуемое количество слов в минуту равно 20, то время бита
должно быть 1200 / 20 = 60 мс.
На рис. 6.98 показана блок-схема проекта.
Рис. 6.98: Блок-схема проекта.
В целом, существует два типа простых недорогих зуммеров: пассивные и активные.
Пассивные зуммеры могут издавать звуки на разных частотах, и на вход таких зуммеров
обычно подается сигнал на требуемой частоте. Активные зуммеры, с другой стороны,
генерируют одиночный тон при подаче логической единицы на их выводы. В этом проекте
для простоты используется активный зуммер.
● 218
Chapter 6 • Amateur Radio Hardware-based Projects
Зуммер подключен к выводу GP16 Raspberry Pi Pico через транзисторный переключатель на
биполярномтранзисторе(любойNPN-транзистор).Транзисторныйпереключатель используется
здесь для увеличения громкости зуммера (рис. 6.99).
Рис. 6.99: Схема проекта.
Листинг программы показан на рис. 6.100 (Программа:Morse.py). В начале программы вывод
порта GP16 настроен как выход. Затем азбука Морзе, состоящая из букв, цифр и некоторых
символов, определяется в виде словаря и хранится в переменной MorseCode. Функции
dotanddash отправляют точку и тире в нужное время. Функция dot активирует зуммер на одну
единицу времени, а функция dash — на 3 единицы времени. Затем пользователю
предлагается ввести требуемую скорость в словах в минуту, которая сохраняется в
переменной wpm. Затем определяются время между точками, время между тире, время
между символами и время между словами.
Внутри цикла программы пользователю предлагается ввести текст, азбука Морзе которого
должна быть отправлена на зуммер, и этот текст сохраняется в переменной data. Затем
символы из data считываются, преобразуются в верхний регистр, из словаря считывается
эквивалентная азбука Морзе, и если это точка, вызывается функция dot, если это тире,
вызывается функция dashi, если это пробел, то предполагается межсловный пробел и
вводится задержка. Символы отображаются на экране по мере их преобразования в азбуку
Морзе и отправки на зуммер.
Обратите внимание, что, как было описано ранее, в конце символа мы не вставляем точку, а
вставляем интервал между символами (3 единицы). Аналогично, в конце слова мы не
вставляем точку, а вставляем интервал между словами (7 единиц). Если точка — последний
символ в символе, а следующий символ — другой символ, и мы определяем точку как
включение звукового сигнала, затем задержку в одну единицу, затем выключение звукового
сигнала и задержку в одну единицу, то нам необходимо установить межсимвольное время
равным 2 единицам, а не 3. Аналогично, если тире — последний символ в символе, а
следующий символ — другой символ, и мы определяем тире как включение звукового сигнала,
затем задержку в 3 единицы, затем выключение звукового сигнала и задержку в одну единицу,
то нам необходимо установить межсловное время равным 2 единицам, а не 3. Если
следующий символ — пробел (следующее слово), то задержка должна быть установлена
равной 6 единицам, а не 7.
● 219
Raspberry Pi Pico for Radio Amateurs
#----------------------------------------------------------------#
УПРАЖНЕНИЕ ПО АЗБУКЕ МОРЗЕ
#
============================
#
# Это программа для тренировки азбуки Морзе. Пользователь вводит
# скорость (слов в минуту), а затем текст. Текст преобразуется # в азбуку Морзе
# и отправляется на зуммер (или светодиод, или реле).
#
# Author: Dogan Ibrahim
# File
: Morse.py
# Date
: Sept 2021
#------------------------------------------------------------------from machine import Pin
import utime
# Импорт времени
Buzzer = Pin(16, Pin.OUT)
# Buzzer pin
Buzzer.value(0)
# Buzzer OFF
#
# Таблица азбуки Морзе как словарь
#
MorseCode = {' ': ' ',
'0': '-----',
'1': '.----',
'2': '..---',
'3': '...--',
'4': '....-',
'5': '.....',
'6': '-....',
'7': '--...',
'8': '---..',
'9': '----.',
':': '---...',
';': '-.-.-.',
'?': '..--..',
'/': '-..-.',
'.': '.-.-.-',
',': '--..--',
'A': '.-',
'B': '-...',
'C': '-.-.',
'D': '-..',
'E': '.',
'F': '..-.',
'G': '--.',
'H': '....',
● 220
Chapter 6 • Amateur Radio Hardware-based Projects
'I': '..',
'J': '.---',
'K': '-.-',
'L': '.-..',
'M': '--',
'N': '-.',
'O': '---',
'P': '.--.',
'Q': '--.-',
'R': '.-.',
'S': '...',
'T': '-',
'U': '..-',
'V': '...-',
'W': '.--',
'X': '-..-',
'Y': '-.--',
'Z': '--..'}
#
# выход точки
#
def Dot():
Buzzer.value(1)
utime.sleep(DotTime)
Buzzer.value(0)
utime.sleep(DotTime)
#
# Производительность в день
#
def Dash():
Buzzer.value(1)
utime.sleep(DashTime)
Buzzer.value(0)
utime.sleep(DotTime)
#
# Получив необходимое количество слов в минуту, рассчитайте время.
#
wpm = int(input("Required words per minute: "))
UnitTime = 1.2/wpm
DotTime = UnitTime
InterCharTime = 2 * UnitTime
DashTime = 3 * UnitTime
WordTime = 6* UnitTime
● 221
Raspberry Pi Pico for Radio Amateurs
while True:
data = input("Enter the text to convert to Morse code: ")
print("
",end="")
for letters in data:
print(letters,end="")
for code in MorseCode[letters.upper()]:
if code == '-':
Dash()
elif code == '.':
Dot()
elif code == ' ':
utime.sleep(WordTime)
utime.sleep(InterCharTime)
print("")
print("")
Рис. 6.100: Программа: Morse.py.
На рис. 6.101 показан пример запуска программы. Здесь количество слов в минуту
установлено на 12, а предложение Привет от Raspberry Pi Pico преобразуется в
азбуку Морзе. Обратите внимание, что символы введенного текста отображаются
под текстом, поскольку они преобразуются в код Морзе и отправляются на зуммер.
Рис. 6.101: Пример выполнения программы.
6.12.2 Проект 22: Отправка случайно сгенерированных символов
В этом проекте случайные символы будут генерироваться из словаря азбуки Морзе,
преобразовываться в азбуку Морзе и отправляться на зуммер. Символы будут отображаться
на экране компьютера по мере преобразования.
Блок-схема и принципиальная схема проекта представлены в предыдущем разделе.
На рис. 6.102 показан листинг программы (Program:Morse2.py). Большая часть этой
программы аналогична рис. 6.100. Как и прежде, программа запрашивает у пользователя
требуемое количество слов в минуту и количество генерируемых символов. Затем
генерируется случайное целое число от 1 до 42 (размер словаря азбуки Морзе). Это число
используется для индексации словаря и получения случайного символа и его кода Морзе.
Затем этот код отправляется на зуммер. Обратите внимание, что формируются два списка с
именами value и keys из словаря азбуки Морзе, и эти списки индексируются случайным
числом. Символы, отправленные на зуммер, также отображаются на экране компьютера.
● 222
Chapter 6 • Amateur Radio Hardware-based Projects
#----------------------------------------------------------------#
Упражнение по азбуке Морзе
#
========================
#
# Это программа для тренировки азбуки Морзе. Программа генерирует
# случайные символы, которые преобразуются в азбуку Морзе и отправляются
# на зуммер.
#
# Author: Dogan Ibrahim
# File
: Morse2.py
# Date
: Sept 2021
#------------------------------------------------------------------from machine import Pin
# Импорт RPi
import utime # Импорт времени
import random # Импорт случайных чисел
Buzzer = Pin(16, Pin.OUT)
# Buzzer pin
Buzzer.value(0) # Buzzer OFF
#
# Morse code table as a dictionary
#
MorseCode = {' ': ' ',
'0': '-----',
'1': '.----',
'2': '..---',
'3': '...--',
'4': '....-',
'5': '.....',
'6': '-....',
'7': '--...',
'8': '---..',
'9': '----.',
':': '---...',
';': '-.-.-.',
'?': '..--..',
'/': '-..-.',
'.': '.-.-.-',
',': '--..--',
'A': '.-',
'B': '-...',
'C': '-.-.',
'D': '-..',
'E': '.',
'F': '..-.',
'G': '--.',
● 223
Raspberry Pi Pico for Radio Amateurs
'H': '....',
'I': '..',
'J': '.---',
'K': '-.-',
'L': '.-..',
'M': '--',
'N': '-.',
'O': '---',
'P': '.--.',
'Q': '--.-',
'R': '.-.',
'S': '...',
'T': '-',
'U': '..-',
'V': '...-',
'W': '.--',
'X': '-..-',
'Y': '-.--',
'Z': '--..'}
#
# Output a dot
#
def Dot():
Buzzer.value(1)
utime.sleep(DotTime)
Buzzer.value(0)
utime.sleep(DotTime)
#
# Вывести тире
#
def Dash():
Buzzer.value(1)
utime.sleep(DashTime)
Buzzer.value(0)
utime.sleep(DotTime)
#
# Получите необходимое количество слов в минуту, рассчитайте время.
#
wpm = int(input("Required words per minute: "))
UnitTime = 1.2/wpm
DotTime = UnitTime
InterCharTime = 2 * UnitTime
DashTime = 3 * UnitTime
● 224
Chapter 6 • Amateur Radio Hardware-based Projects
WordTime = 6* UnitTime
values = MorseCode.values()
values_list = list(values)
keys = MorseCode.keys()
keys_list = list(keys)
cnt = 0
count = int(input("How many charactetrs to generate?: "))
while cnt < count:
# Выполнять бесконечно
r = random.randint(1, 42)
# Случайное число
c = values_list[r]
# Получить значение
# Получить его ключ
# Отобразить ключ
d = keys_list[r]
print(d, end="")
for code in c:
if code == '-':
# Выполните для кода
# Если дефис
Dash()
elif code == '.':
# если точка
Dot()
utime.sleep(InterCharTime)
cnt = cnt + 1
Рис. 6.102: Программа:Morse2.py..
Пример выполнения программы показан на рис. 6.103, где было сгенерировано 10 символов.
Рис. 6.103: Пример выполнения программы.
6.12.3 Проект 23: Настройка скорости азбуки Морзе с помощью ЖК-дисплея и
поворотного энкодера
В этом проекте мы будем использовать ЖК-дисплей и поворотный энкодер для установки
скорости генерируемого кода Морзе. Поворот ручки поворотного энкодера увеличивает
скорость в словах в минуту, а поворот в обратную сторону уменьшает ее. Как и в
предыдущем проекте, будут генерироваться случайные символы, которые будут
преобразованы в коды Морзе и затем отправлены на зуммер. Сгенерированные символы
будут отображаться в нижней строке ЖК-дисплея.
На рис. 6.104 показана блок-схема проекта.
● 225
Raspberry Pi Pico for Radio Amateurs
Рис. 6.104: Блок-схема проекта.
Поворотный энкодер — это устройство, похожее на потенциометр, которое реагирует на
вращение и направление поворота ручки. Устройство имеет два внутренних контакта, которые
замыкают и размыкают цепь при повороте ручки. При повороте ручки ощущается щелчок,
указывающий на то, что ручка повернулась на одно положение. С помощью простой логики мы
можем определить направление вращения.
Поворотный энкодер имеет следующие пины:
GND: земля
Vcc (+): плюс источника питания
CLK: Это выходной контакт, используемый для определения угла поворота. При
каждом повороте ручки на один щелчок в любом направлении выход CLK переходит в
состояние ВЫСОКОГО уровня, а затем в состояние НИЗКОГО уровня.
DT: Это выход, аналогичный контакту CLK, но он отстает от CLK на 90 градусов. Он
используется для определения направления поворота.
SW: Это активная кнопка низкого уровня. При нажатии на ручку напряжение
переходит в состояние НИЗКОГО уровня.
В нашем проекте каждое вращение (т.е. щелчок) ручки увеличивает (или уменьшает)
количество слов в минуту на 1. Поворот ручки в одном направлении увеличивает счетчик на
единицу, а поворот в другом — уменьшает на единицу. Когда достигается требуемое
значение, пользователь должен нажать на ручку, чтобы программа начала генерировать
случайные символы азбуки Морзе на зуммере.
На рис. 6.105 показана принципиальная схема проекта. ЖК-дисплей I2C подключен к
Raspberry Pi Pico, как и в предыдущих проектах на основе ЖК-дисплея, где контакты SDA и
SCL подключены к выводам GP2 и GP3 соответственно. Зуммер подключен к выводу GP26
через транзисторный переключатель, как и в предыдущем проекте. Поворотный энкодер
подключен следующим образом:
Rotary encoder
GPIO pin
CLK GP6
DT GP7
SW GP8
GND GND
Vcc(+) 3.3V
● 226
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.105: Схема проекта.
На рис. 6.106 показан листинг программы (программа: Morse3.py). В начале программы
импортируется библиотека LCD и определяется тип LCD. Затем определяется интерфейс
между поворотным энкодером и Raspberry Pi Pico, а контакты CLK, DT и SW поворотного
энкодера настраиваются как входы.
Значение количества слов в минуту увеличивается или уменьшается по мере поворота
пользователем ручки поворотного энкодера по часовой или против часовой стрелки
соответственно. Минимальное значение равно 1. LCD отображает количество слов в минуту
в любой момент времени. Нажатие на ручку поворотного энкодера запускает цикл
программы, в котором генерируются случайные символы, и их коды Морзе отправляются на
зуммер. LCD отображает символы в реальном времени по мере их случайной генерации
программой. Программа настроена на генерацию 16 символов, но это легко можно изменить
при необходимости.
#----------------------------------------------------------------#
Упражнение по азбуке Морзе
#
=======================
#
# Это программа для тренировки азбуки Морзе. Программа
# генерирует случайные символы, которые преобразуются в азбуку
# Морзе и отправляются на зуммер. В этой программе скорость
# устанавливается с помощью поворотного энкодера и ЖК-дисплея
# I2C. Поворот поворотного энкодера увеличивает или уменьшает
# скорость в словах в минуту. Нажатие на ручку запускает генерацию азбуки Морзе.
# Сгенерированные символы отображаются в нижней строке ЖК-дисплея.
#
# Author: Dogan Ibrahim
# File
: Morse3.py
# Date
: Sept 2021
#-------------------------------------------------------------------
● 227
Raspberry Pi Pico for Radio Amateurs
from machine import Pin, I2C
# Import Pin,I2C
import utime # Время импорта
import random # Импорт случайного числа
from pico_i2c_lcd import I2cLcd
#
# Модуль ЖК-дисплея с интерфейсом I2C подключен к контактам SDA1 и SCL1.
#
i2c_lcd = I2C(id=1,scl=Pin(3),sda=Pin(2),freq=100000)
lcd = I2cLcd(i2c_lcd, 0x27, 2, 16)
Buzzer = Pin(16, Pin.OUT)
# Buzzer pin
Buzzer.value(0) # Buzzer OFF
#
# Соединения поворотного энкодера
#
CLK = Pin(6, Pin.IN)
# CLK pin
DT = Pin(7, Pin.IN)
# DT pin
SW = Pin(8, Pin.IN, Pin.PULL_UP)
# SW pin
#
# Таблица азбуки Морзе в виде словаря
#
MorseCode = {' ': ' ',
'0': '-----',
'1': '.----',
'2': '..---',
'3': '...--',
'4': '....-',
'5': '.....',
'6': '-....',
'7': '--...',
'8': '---..',
'9': '----.',
':': '---...',
';': '-.-.-.',
'?': '..--..',
'/': '-..-.',
'.': '.-.-.-',
',': '--..--',
'A': '.-',
'B': '-...',
'C': '-.-.',
'D': '-..',
'E': '.',
● 228
Chapter 6 • Amateur Radio Hardware-based Projects
'F': '..-.',
'G': '--.',
'H': '....',
'I': '..',
'J': '.---',
'K': '-.-',
'L': '.-..',
'M': '--',
'N': '-.',
'O': '---',
'P': '.--.',
'Q': '--.-',
'R': '.-.',
'S': '...',
'T': '-',
'U': '..-',
'V': '...-',
'W': '.--',
'X': '-..-',
'Y': '-.--',
'Z': '--..'}
#
# Вывести точку
#
def Dot():
Buzzer.value(1)
utime.sleep(DotTime)
Buzzer.value(0)
utime.sleep(DotTime)
#
# Вывести тире
#
def Dash():
Buzzer.value(1)
utime.sleep(DashTime)
Buzzer.value(0)
utime.sleep(DotTime)
wpm = 1
ClkOldState = CLK.value()
# Значение по умолчанию
# Получить состояние CLK
flag = 1
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr("Enter WPM:")
# Очистить ЖК-экран
# В точке (0,0)
# Заголовок
● 229
Raspberry Pi Pico for Radio Amateurs
lcd.move_to(0, 1)
lcd.putstr("1")
#
# Получите необходимое количество слов в минуту. Пользователь поворачивает
# поворачивает поворотный энкодер, чтобы установить скорость печати.
#
while flag == 1:
ClkState = CLK.value()
DTState = DT.value()
if ClkState != ClkOldState and ClkState == 1:
if DTState != ClkState:
wpm = wpm + 1
else:
wpm = wpm - 1
if wpm == 0:
wpm = 1
lcd.move_to(0, 1)
lcd.putstr("
")
lcd.move_to(0, 1)
lcd.putstr(str(wpm))
ClkOldState = ClkState
# Получить состояние SW
# Ручка нажата?
# Очистить флаг
SWState = SW.value()
if SWState == 0:
flag = 0
#
# Мы оказываемся здесь, когда пользователь нажимает на ручку поворотного энкодера.
#
UnitTime = 1.2/wpm
DotTime = UnitTime
InterCharTime = 2 * UnitTime
DashTime = 3 * UnitTime
WordTime = 6* UnitTime
values = MorseCode.values()
values_list = list(values)
keys = MorseCode.keys()
keys_list = list(keys)
lcd.clear()
lcd.move_to(0, 0)
s = "Working: " + str(wpm) + " wpm"
# Очистить ЖК-экран
# В точке (0, 0)
# Заголовок
lcd.putstr(s)
lcd.move_to(0, 1)
● 230
# В точке (1, 0)
Chapter 6 • Amateur Radio Hardware-based Projects
col = 0
#
# Коды Морзе генерируются в цикле ниже.
# Генерируется 16 символов
#
# (можно легко изменить)
count = 0
while count < 16:
# Сгенерировать 16 символов
r = random.randint(1, 42)
# Случайное число
c = values_list[r]
# Получить значение
d = keys_list[r]
# Получить его клавишу
lcd.putstr(d)
# Отобразить символы
col = col + 1
if col > 16:
col = 0
lcd.move_to(0, 1)
lcd.putstr("
")
lcd.move_to(0, 1)
for code in c:
if code == '-':
# Выполните для кода
# Если дефис
Dash()
elif code == '.':
# если точка
Dot()
utime.sleep(InterCharTime)
count = count + 1
Рис. 6.106 Программа: Morse3.py.
Рис. 6.107 показывает примеры отображения на ЖК-дисплее. Выход можно подключить к
реле и затем управлять CW-передатчиком.
Рис. 6.107: Примеры отображения.
● 231
Raspberry Pi Pico for Radio Amateurs
6.13 Проект 24: Релейный секвенсор с временными задержками
В любительской радиосвязи существуют приложения, где необходимо активировать
несколько реле в заданном порядке и с заданными временными задержками между
каждым включением. Например, нам нужно убедиться, что передающее/приёмное реле
активировано перед запуском трансивера. Также может потребоваться включать и
выключать различное оборудование в строгом порядке с заданными временными
задержками.
В этом проекте к Raspberry Pi Pico подключены 4 реле. Кроме того, подключены две кнопки с
названиями ON и OFF. Нажатие кнопки ON активирует реле в заданной последовательности
включения и с заданной временной задержкой между каждым включением. Аналогично,
нажатие кнопки OFF деактивирует реле в заданной последовательности выключения и с
заданной временной задержкой между каждым включением.
На рис. 6.108 показана блок-схема проекта.
Рис. 6.108: Блок-схема проекта.
В этом проекте используется 4-канальная релейная плата (см. рис. 6.2) от компании Elegoo
(www.elegoo.com). Это плата с оптоэлектронной связью, имеющая 4 входа, по одному для
каждого канала. Входы реле расположены в правом нижнем углу платы, а выходы — в
верхнем. Среднее положение каждого реле является общей точкой. Соединение слева от него
— это нормально замкнутый (NC) контакт, а соединение справа — нормально разомкнутый
(NO) контакт. Контакты реле поддерживают напряжение 250 В переменного тока при токе 10 А
и 30 В постоянного тока при токе 10 А. IN1, IN2, IN3 и IN4 — это активные входы с низким
уровнем сигнала, что означает, что реле активируется при подаче логического сигнала низкого
уровня на его входной контакт. Контакты реле являются нормально замкнутыми (NC).
Активация реле изменяет активные контакты таким образом, что общий контакт и контакт NC
становятся двумя контактами реле. Одновременно загорается светодиод на входной цепи
платы реле, соответствующий активированному реле. Напряжение VCC может быть
подключено либо к +3,3 В, либо к +5 В. Перемычка JD используется для выбора напряжения
для реле.
Поскольку ток, потребляемый реле, может превышать 80 мА, необходимо снять эту
перемычку и подключить внешний источник питания (например, +5 В) к выводу JD-VCC.
Кнопки ON и OFF используются для включения и выключения реле соответственно.
Схема проекта показана на рис. 6.109. Кнопки ON и OFF подключены к выводам портов GP0 и
GP1 соответственно. Выходы кнопок программно подтянуты к высокому уровню и переходят в
логический 0 при нажатии соответствующей кнопки. Контакты IN1, IN2, IN3 и IN4 релейного
модуля подключены к контактам портов GP6, GP7, GP8 и GP9 соответственно. Контакты реле
должны быть подключены к оборудованию, которое необходимо включать/выключать, через
сеть переменного тока (ВНИМАНИЕ: при работе с сетью следует соблюдать осторожность).
● 232
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.109: Схема проекта.
На рис. 6.110 показан листинг программы (программа: relaysequencer.py). В начале программы
определяется подключение кнопок и реле к Raspberry Pi Pico. Контакты портов, к которым
подключены входные контакты реле IN1 – IN4, настроены как выходы. Контакты портов, к
которым подключены контакты кнопок ON и OFF, настроены как входы, и эти контакты
внутренне подтянуты к высокому уровню Raspberry Pi Pico. Массив IN[] хранит номера
контактов портов для выходов. То есть, 6, 7, 8 и 9. В начале программы все четыре реле
выключаются. Массивы ONOrder и OFFOrder определяют порядок включения и выключения
реле. Аналогично, массивы ONDelays и OFFDelays определяют временные задержки между
включениями реле. Первые задержки отсчитываются относительно нажатия кнопок ON или
OFF. Следующие задержки отсчитываются относительно предыдущих. Пример приведен ниже:
ONOrder = (1, 2, 4, 3)
OFFOrder = (1, 3, 4, 2)
ONDelays = (5, 5, 8, 10)
OFFDelays = (5, 5, 5, 8)
В этом примере нажатие кнопки ON активирует реле 1 через 5 секунд. Реле 2 активируется
через 10 секунд, реле 4 — через 18 секунд, а реле 3 — через 28 секунд. Нажатие кнопки OFF
сначала деактивирует реле 1 через 5 секунд. Реле 3 будет деактивировано через 10 секунд,
реле 4 — через 15 секунд, а реле 2 — через 23 секунды.
Основная программа выполняется внутри цикла основной программы, где используется цикл
while. В программе используются две функции: Activate() и Deactivate(). Функция Activate()
активирует четыре реле с заданной последовательностью и временными задержками. Ее
тело состоит из следующего кода:
● 233
Raspberry Pi Pico for Radio Amateurs
def Activate():
for i in range(0, 4):
r = ONOrder[i]
relay = IN[r-1]
d = ONDelays[i]
utime.sleep(d)
relay.value(0)
Переменная `r` хранит последовательность включения реле, а переменная `d` хранит
значение задержки включения для данного реле.
Аналогично, функция `Deactivate()` деактивирует четыре реле с заданной
последовательностью и временными задержками. Её тело состоит из следующего кода:
def Deactivate():
for i in range(0, 4):
r = OFFOrder[i]
relay = IN[r-1]
d = OFFDelays[i]
utime.sleep(d)
relay.value(1)
Код устроен таким образом, что функция Deactivate() не может быть вызвана до активации
реле. Аналогично, функция Activate() не может быть вызвана повторно до деактивации реле.
Программа останавливается, и все реле отключаются, как только нажимается кнопка Thonny
Stop или нажимаются кнопки Ctrl+C на клавиатуре.
#--------------------------------------------------------------РЕЛЕЙНЫЙ СЕКВЕНСОР С ВРЕМЕННЫМИ ЗАДЕРЖКА
#
#
--------------------------------
# В этом проекте к Raspberry Pi Pi подключены 2 кнопки и 4 реле.
# Реле включаются/выключаются по порядку с заданными задержками
# Задержки отсчитываются относительно заданного
# предыдущего значения задержки.
#
# Author: Dogan Ibrahim
# File
: relaysequencer.py
# Date
: Sept 2021
#--------------------------------------------------------------from machine import Pin
import utime
IN = [0]*4
#
● 234
Chapter 6 • Amateur Radio Hardware-based Projects
# Подключение кнопок
#
ON = Pin(0, Pin.IN, Pin.PULL_UP)
OFF = Pin(1, Pin.IN, Pin.PULL_UP)
#
# Подключение реле (выходов)
#
for i in range(0, 4):
IN[i] = Pin(i+6, Pin.OUT)
# Relay pins
IN[i].value(1)
# Relays OFF
ONOrder = (1, 2, 4, 3)
OFFOrder = (1, 3, 2, 4)
ONDelays = (5, 5, 5, 5)
OFFDelays = (5, 5, 5, 10)
#
# Эта функция активирует реле в указанном порядке и
# с указанными задержками между каждым реле.
#
def Activate():
for i in range(0, 4):
r = ONOrder[i]
relay = IN[r-1]
d = ONDelays[i]
utime.sleep(d)
relay.value(0)
#
# Эта функция деактивирует реле в указанном порядке и
# с задержками между каждым реле.
#
def Deactivate():
for i in range(0, 4):
r = OFFOrder[i]
relay = IN[r-1]
d = OFFDelays[i]
utime.sleep(d)
relay.value(1)
#
# Эта функция проверяет, нажата ли кнопка ON или OFF.
#
Act = 0
Deact = 1
● 235
Raspberry Pi Pico for Radio Amateurs
try:
while True:
if ON.value() == 0 and Act == 0 and Deact == 1:
# ON pushed
Activate()
# Activate
Act = 1
Deact = 0
if OFF.value() == 0 and Deact == 0 and Act == 1:
# OFF pushed
Deactivate()
# Deactivate
Deact = 1
Act = 0
utime.sleep(0.1)
except KeyboardInterrupt:
for i in range(0, 4):
IN[i].value(1)
# Все выключено
Рис. 6.110: Программа: relayssequencer.py.
6.14 Проект 25: FM-радио с Raspberry Pi Pico
FM-радиоприемники сегодня чрезвычайно популярны, поскольку в FM-диапазоне доступно
множество станций на выбор. Качество звука FM-радиоприемников также превосходное, и
большинство станций по всему миру обеспечивают стереофоническое вещание.
Это проект FM-радио, основанный на модуле FM-радио TEA5767. Это недорогой модуль
FM-радио, стоимостью около 10 долларов. Модуль (рис. 6.111) подключается к внешнему
миру через контакты I2C (SDA и SCL). Он имеет 4 контакта; оставшиеся два контакта
предназначены для питания и заземления. На модуле предусмотрены два небольших
разъема: один для антенны, а другой для наушников. В комплект модуля входит небольшая
цельная антенна с разъемом. Пользователю нужно всего лишь подключить наушники и
запрограммировать модуль на необходимую частоту. Антенна подключается к левому
разъему, если смотреть на сторону модуля с компонентами, а наушники — к другому разъему.
● 236
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.111: FM-радиомодуль TEA5767.
TEA5767 — это однокристальный стереофонический FM-радиоприемник с электронной
настройкой, предназначенный для низковольтных применений, включающий селективность
ПЧ и демодуляцию. Модуль обладает следующими характеристиками:
• работа в американском/европейском FM-диапазоне от 87,5 МГц до 108 МГц и
японском FM-диапазоне от 76 МГц до 91 МГц
•
•
•
•
•
•
•
•
•
•
•
•
•
•
схема автоматической регулировки усиления (AGC)
система настройки синтезатора с фазовой автоподстройкой частоты (PLL)
кварцевый генератор опорной частоты
интерфейс шины I2C, требующий всего 2 контакта
программное отключение звука
смешивание моно и стереосигналов в зависимости от сигнала
управление высокочастотным фильтром (HCC) в зависимости от сигнала
функция автономного поиска настройки
режим ожидания
два программируемых порта
питание от 2,5 В до 5 В
типичный аналоговый ток питания 8,4 мА, цифровой ток питания 3 мА
разделение стереоканалов 30 дБ
типичные гармонические искажения 0,4%
Адрес I2C по умолчанию для модуля — 0x60. Последовательность данных должна быть
следующей: адрес, байт 1, байт 2, байт 3, байт 4 и байт 5. Младший значащий бит (LSB) = 0
адреса указывает на операцию записи в TEA5767HN. Бит 7 каждого байта считается старшим
значащим битом (MSB) и должен передаваться как первый бит байта. Данные становятся
действительными побитово по соответствующему спадающему фронту тактового сигнала.
Условие STOP после любого байта может сократить время передачи. При сбросе питания
устанавливается отключение звука, а все остальные биты устанавливаются в низкий уровень.
● 237
Raspberry Pi Pico for Radio Amateurs
Программирование микросхемы TEA5767 осуществляется путем загрузки 5 байтов данных в ее
регистры через шину I2C. В таблицах 5–16 технического описания указаны данные, которые
необходимо загрузить для различных конфигураций устройства. Например, первый байт данных
состоит из следующих битов:
Bit 7: бит отключения звука. Установка этого бита отключает радио. Для нормальной
работы его необходимо сбросить.
Bit 6: бит режима поиска. Установка этого бита переводит микросхему в режим
поиска. Для нормальной работы его необходимо сбросить.
Bit 0 – 5: старшие 6 бит требуемой частоты. Второй байт содержит 8 младших битов
требуемой частоты.
Частота задается как 14 бит путем загрузки в регистр ФАПЧ. Данные для загрузки в регистр
ФАПЧ задаются следующим образом:
Where
N = десятичное значение слова PLL
желаемая частота настройки в Гц
— это промежуточная частота в Гц (225 кГц)
— это опорная частота в Гц (32768).
Например, для приема трансляции на частоте 100 МГц требуется следующее слово ФАПЧ:
Эти данные необходимо разделить на два байта, при этом верхние 8 бит загружаются как
байт данных 1 (с отключенными параметрами отключения звука и поиска), а нижние 8 бит —
как байт данных 2. Это можно сделать следующим образом:
Верхний байт = N >> 8 Нижний байт = N & 0xFF
Третий байт данных определяет режим поиска, моно-стерео работу и отключение звука слева
и справа. Четвертый байт данных определяет режим ожидания, пределы полосы пропускания,
частоту тактирования, шумоподавление и т. д. Пятый байт данных управляет опорной
частотой ФАПЧ и предполагаемой постоянной времени фазы.
● 238
Chapter 6 • Amateur Radio Hardware-based Projects
На рис. 6.112 показана блок-схема проекта. Наушники подключены к выходу модуля TEA5767.
Рис. 6.112: Блок-схема проекта.
Схема подключения показана на рис. 6.113. Контакты SDA0 (GP1) и SCL0 (GP0) Raspberry
PiPico подключены к радиомодулю, который питается от +3,3 В Pico.
Рис. 6.113: Схема проекта.
Рис. 6.114 показывает листинг программы. Программа:fmradio.py) состоит из
следующих функций:
init(): Эта функция инициализирует модуль TEA5767.
set_freq(freq): Эта функция принимает требуемую частоту станции в качестве
параметра. Функция загружает 5 байтов данных для начала приема трансляции на
этой частоте. В начале функции N используется для установки значения ФАПЧ для
требуемой частоты, как показано в приведенной выше формуле. Nupper и Nlower —
это верхний и нижний байты N соответственно. Обратите внимание, что бит
отключения звука (бит 7) сбрасывается, чтобы модуль не находился в режиме
отключения
● 239
Raspberry Pi Pico for Radio Amateurs
Массив buff используется для хранения байтов данных. Первые две ячейки buff[0] и
buff[1] массива buff загружаются верхним и нижним байтами N.
buff[2] загружен с включенными следующими битами (см. техническое описание TEA5767):
Bit
7
6,5
4
0-3
Symbol Определение
SUD
включить поиск вверх
SSL
низкий уровень остановки поиска
HLSI
ввод гетеродина на стороне L0
MS,MR,ML,SWP1
mute не включено; порт SWP1 находится
в низком состоянии
buff[3] и buff[4] загружаются таким образом, что тактовая частота устанавливается на
32,768 кГц (см. техническое описание TEA5767). Затем 5-байтовые данные буфера
загружаются в микросхему с помощью функции I2C i2c.writeto. Установленная частота
отображается на экране.
Mute(address): эта функция отключает звук модуля, так что не принимается
широковещательная передача и не слышен выходной сигнал. Здесь частота устанавливается
на 0, а бит отключения звука (бит 7) устанавливается в buff[0]. Остальные байты остаются
такими же, как в функции set_freq. На экране отображается сообщение «Радио отключено…».
В основной программе частота изначально устанавливается на 101,4 МГц, что соответствует
частоте вещания местной радиостанции. Затем пользователю предлагается ввести команду
из 1 символа. Эти команды используются либо для выбора заданных по умолчанию частот,
либо для увеличения/уменьшения частоты. Допустимые команды и их значения приведены
ниже:
Значение
Команда
начать
прием
с местной станции по умолчанию на частоте 101,4 МГц
f
начать
прием
со следующей популярной местной станции,установить на 102,0 МГц
n
величить частоту на 1 МГц
+
уменьшить частоту на 1 МГц
увеличить частоту на 0,1 МГц
>
увеличить частоту на 0,1 МГц,
<
уменьшить частоту на 0,1 МГц
отключить звук
m
включить звук
u
выход (отключить звук и выйти). Отобразится сообщение: Выход - Exiting
q
#----------------------------------------------------------------#
FM RADIO
#
========
#
# Это FM-радио, использующее радиомодуль TEA5767. Модуль
# работает с сигналами I2C SDA и SCL,
# подключенными к SCL0 и SDA0 Raspberry Pi Pico.
#
# Author: Dogan Ibrahim
# File
● 240
: fmradio.py
Chapter 6 • Amateur Radio Hardware-based Projects
# Date
: August 2021
#------------------------------------------------------------------from machine import I2C, Pin
import utime
buff = [0]*5
print("TEA5767 FM RADIO")
print("================")
#
# Радиомодуль TEA5767 подключен к SDA0, SCL0
#
i2c = machine.I2C(0, scl=Pin(1), sda=Pin(0), freq=100000)
print("i2c address (dec) = ", i2c.scan())
address = 0x60 # Address
def init():
buff[0] = 0x80
i2c.writeto(address, bytearray(buff))
utime.sleep(0.2)
#
# Эта функция устанавливает требуемую частоту радио
#
def set_freq(freq):
N = int (4 * (freq * 1000000 + 225000) / 32768)
Nupper = N >> 8
Nlower = N
& 0xFF
buff[0] = Nupper
buff[1] = Nlower
buff[2] = 0xB0
buff[3] = 0x10
buff[4] = 0x00
i2c.writeto (address, bytearray(buff))
print("Frequency set to: " + str(freq))
#
# Эта функция отключает радио
#
def mute(address):
N = int(4 * (0 * 1000000 + 225000) / 32768)
Nlower = N & 0xFF
buff[0] = 0x80
buff[1] = Nlower
● 241
Raspberry Pi Pico for Radio Amateurs
buff[2] = 0xB0
buff[3] = 0x10
buff[4] = 0x00
i2c.writeto(address, bytearray(buff))
print("Radio Muted...")
init()
frequency = 101.4
# Starting frequency
try:
while True:
c = input("command (fn+-><muq): ")
print(c)
if c == 'f':
# Установить на 101.4
frequency = 101.4
set_freq(frequency)
utime.sleep(1)
elif c == 'n':
# Установить на 102.0
frequency = 102.0
set_freq(frequency)
utime.sleep(1)
elif c == '+':
# Увеличить на 1 МГц
frequency = frequency + 1
set_freq(frequency)
utime.sleep(1)
elif c == '-':
# Уменьшить на 1 МГц
frequency = frequency - 1
set_freq(frequency)
utime.sleep(1)
elif c == '>':
# Увеличить на 0.1 МГц
frequency = frequency + 0.1
set_freq(frequency)
utime.sleep(1)
elif c == '<':
# Уменьшить на 0.1 МГц
frequency -= 0.1
set_freq(frequency)
utime.sleep(1)
elif c == 'm':
# Отключить звук
mute(address)
utime.sleep(1)
elif c == 'u':
# Включить звук
set_freq(frequency)
utime.sleep(1)
elif c == 'q':
● 242
# Mute and Exit
Chapter 6 • Amateur Radio Hardware-based Projects
mute(address)
print("Exitting")
break
except KeyboardInterrupt:
print("Command error")
Рис. 6.114 Программа: fmradio.py.
Проверка радио
•
•
•
•
построить схему
подключите антенну и наушники к модулю
написать/скопировать программу
запустите программу. По умолчанию радио будет принимать вещание
на частоте 101,4 МГц (при необходимости измените это значение).
Используйте команды для увеличения/уменьшения частоты по мере
необходимости. Вы должны принимать трансляции на наушники.
Для завершения введите q, а затем нажмите Enter.
На рис. 6.115 показан пример запуска программы.
Рис. 6.115: Пример запуска программы.
На рис. 6.116 показана радиостанция, построенная на макетной плате, и соединения,
выполненные с Raspberry PiPico с помощью перемычек.
● 243
Raspberry Pi Pico for Radio Amateurs
Рис. 6.116: Радиоприемник, построенный на макетной плате.
6.14.1 Проект 26: Модифицированное FM-радио – увеличение уровня
выходного сигнала – подключение громкоговорителя
В предыдущем проекте нам приходилось использовать наушники для прослушивания наших
станций. Усилитель мощности звука можно использовать для увеличения уровня сигнала, чтобы
радио можно было подключить к громкоговорителю.
На рынке доступно множество недорогих модулей усилителей мощности звука. Пожалуй, одним из
самых дешевых вариантов является использование усилителя звука типа LM386. Недостатком
LM386 является то, что он монофонический, а его выходная мощность может оказаться
недостаточной, поэтому может потребоваться дальнейшее усиление. В этом разделе мы узнаем,
как подключить модуль LM386 к нашему FM-радио.
На рис. 6.117 показан модуль усилителя LM386. Модуль состоит из микросхемы LM386,
потенциометра для регулировки громкости, конденсатора, нескольких резисторов,
4-контактного разъема для подачи аудиовхода и источника питания, а также 2-контактного
разъема с винтовой клеммой для громкоговорителя.
● 244
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.117: Модуль усилителя звука LM386.
Структурная схема доработанного проекта представлена на рис. 6.118, принципиальная схема
– на рис. 6.119. Модуль усилителя работает при +5 В, поступающем с контакта 40 Raspberry Pi
Pico.
Рис. 6.118: Блок-схема доработанного проекта.
Рис. 6.119: Принципиальная схема доработанного проекта.
● 245
Raspberry Pi Pico for Radio Amateurs
Автор рекомендует использовать более мощный модуль усилителя стереозвука. Некоторые
недорогие модели, доступные на Amazon, показаны на рис. 6.120. Заинтересованные
радиолюбители могут предпочесть спроектировать и сконструировать схемы усилителей звука
на основе транзисторов. В проект с усилителем звука также можно добавить регулятор
громкости.
Рис. 6.120: Некоторые недорогие модули усилителей мощности звука.
6.14.2 Проект 27: FM-радио с использованием ЖК-дисплея и внешних кнопок
Этот проект аналогичен предыдущему, но здесь для управления FM-радиомодулем TEA5767
используется ЖК-дисплей и внешние кнопки.
На рис. 6.121 показана блок-схема проекта. Переключатель SPST используется для выбора
скорости приращения и уменьшения частоты: 1 МГц или 0,1 МГц. Используются два кнопки.
Нажатие кнопки UP увеличивает частоту со скоростью, установленной переключателем RATE.
Аналогично, нажатие кнопки DOWN уменьшает частоту на уровне, установленном
переключателем RATE.
Рис. 6.121: Блок-схема проекта.
● 246
Chapter 6 • Amateur Radio Hardware-based Projects
На рис. 6.122 представлена принципиальная схема. Соединения между Raspberry Pi Pico
и внешними компонентами следующие. Обратите внимание, что переключатель скорости
и кнопки в программе находятся в положении High:
Raspberry Pi Pico GPIO
Pin number
Connected to
SDA1
SCL1
4
5
I2C LCD SDA
I2C LCD SCL
SDA0
SCL0
1
2
I2C Radio SDA
I2C Radio SCL
GP6
GP7
GP8
9
10
11
RATE switch
UP pushbutton
DOWN pushbutton
Рис. 6.122: Принципиальная схема проекта.
На рис. 6.123 показан листинг программы (программа: FMradioLcd). В начале программы
определяются соединения ЖК-дисплея, соединения переключателя SPST и кнопок, и они
настраиваются как входы с включенными подтягивающими резисторами. Сообщение:
TEA5767 FM RADIO отображается в верхнем ряду ЖК-дисплея в течение 3 секунд. Затем
определяются I2C-соединения радиомодуля. Функция set_freq такая же, как и в предыдущем
проекте, и функция отключения звука здесь не используется. Основная программа
выполняется в цикле while. Внутри этого цикла шаг изменения частоты устанавливается
равным 1 МГц или 0,1 МГц, а частота по умолчанию равна 101,4 МГц. Затем проверяется
состояние кнопок UP и DOWN. При нажатии кнопки UP частота увеличивается шаг за шагом.
Аналогично, при нажатии кнопки DOWN частота уменьшается на величину, заданную шагом.
● 247
Raspberry Pi Pico for Radio Amateurs
#----------------------------------------------------------------#
FM-РАДИО С ЖК-дисплеем И КНОПКАМИ
#
====================================
#
# Это FM-радио с использованием радиомодуля TEA5767. Модуль
# работает с сигналами I2C SDA и SCL, подключенными к SCL0
# и SDA0 Raspberry Pi Pico. Кроме того, для управления
# радиомодемом подключены ЖК-дисплей I2C# и кнопки
#
# RATE: установите скорость приращения частоты на 1 или 0,1 МГц
# UP: увеличьте частоту на заданный шаг
# DOWN: уменьшение частоты на заданный шаг
#
# Author: Dogan Ibrahim
# File
: FMradioLcd.py
# Date
: Sept 2021
#------------------------------------------------------------------from machine import I2C, Pin
from pico_i2c_lcd import I2cLcd
import utime
#
# Модуль ЖК-дисплея I2C подключен к SDA1, SCL1
#
i2c_lcd = I2C(id=1,scl=Pin(3),sda=Pin(2),freq=100000)
lcd = I2cLcd(i2c_lcd, 0x27, 2, 16)
#
# Определите соединения переключателя SPST и кнопок.
# by software
#
RATE = Pin(6, Pin.IN, Pin.PULL_UP)
UP = Pin(7, Pin.IN, Pin.PULL_UP)
DOWN = Pin(8, Pin.IN, Pin.PULL_UP)
buff = [0]*5
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr("TEA5767 FM RADIO")
utime.sleep(3)
#
# TEA5767 Радиомодуль, подключенный к SDA0, SCL0
#
i2c = machine.I2C(0, scl=Pin(1), sda=Pin(0), freq=100000)
● 248
Chapter 6 • Amateur Radio Hardware-based Projects
address = 0x60 # Address
def init():
buff[0] = 0x80
i2c.writeto(address, bytearray(buff))
utime.sleep(0.2)
#
# Эта функция устанавливает радио на необходимую частоту.
#
def set_freq(freq):
N = int (4 * (freq * 1000000 + 225000) / 32768)
Nupper = N >> 8
Nlower = N
& 0xFF
buff[0] = Nupper
buff[1] = Nlower
buff[2] = 0xB0
buff[3] = 0x10
buff[4] = 0x00
i2c.writeto (address, bytearray(buff))
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr("freq set to:")
lcd.move_to(0, 1)
lcd.putstr(str(freq)+" MHz")
init()
frequency = 101.4
# Стартовая частота
first = 1
while True:
if RATE.value() == 1:
step = 1
# проверьте RATE
# шаг = 1 МГц
else:
step = 0.1
if first == 1:
# шаг = 0.1 MHz
# Первый раз
first = 0
frequency = 101.4
# шаг = 101.4
set_freq(frequency)
utime.sleep(1)
while UP.value() == 1 and DOWN.value() == 1:
pass
● 249
Raspberry Pi Pico for Radio Amateurs
if UP.value() == 0:
frequency = frequency + step
# UP нажата
# Увеличение частоты
while UP.value() == 0:
pass
set_freq(frequency)
utime.sleep(0.1)
if DOWN.value() == 0:
frequency = frequency - step
# Down нажата
# Уменьшение частоты
while DOWN.value() == 0:
pass
set_freq(frequency)
utime.sleep(0.1)
Рис. 6.123: Программа: FMradioLcd.py..
Использование громкоговорителя
Как описано в предыдущем проекте, к проекту можно подключить модуль усилителя звука с
соответствующим динамиком и потенциометром регулировки громкости.
Работа от аккумулятора
Теперь, когда проект не зависит от ПК, мы, возможно, захотим работать с ним от
аккумулятора. Возможно, самый простой вариант — использовать блок питания,
используемый для зарядки мобильных телефонов. Затем Raspberry Pi Pico можно подключить
к блоку питания с помощью кабеля micro USB.
Автоматическая загрузка
При работе независимо от ПК нам надо, чтобы радиопрограмма запускалась сразу после подачи
питания на Raspberry Pi Pico. Механизм автоматической загрузки объясняется в главе 7 и
повторяется здесь. Все, что нам нужно сделать, это сохранить нашу программу
FMradioLcd.pyasmain.py на Raspberry Pi. Затем радиопрограмма будет запускаться
автоматически при каждом включении питания на Raspberry Pi Pico.
Расположение передней панели корпуса радиоприемника
Подходящее расположение лицевой панели нашей радиостанции показано на рис. 6.124.
Структурная схема компонентов внутри корпуса представлена на рис. 6.125.
● 250
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.124: Подходящая компоновка передней панели.
Рис. 6.125: Блок-схема нашего FM-радио.
6.14.3 Проект 28: FM-радио с использованием ЖК-дисплея и энкодера
Этот проект похож на предыдущий, но здесь для установки частоты используется энкодер вместо
переключателя и двух кнопок. Установка частоты с помощью энкодера точна и довольно проста.
Поворот вала энкодера на один щелчок изменяет частоту на 0,1 МГц.
На рис. 6.126 показана блок-схема проекта. Настройки частоты отображаются на ЖК-дисплее по
мере поворота ручки энкодера.
● 251
Raspberry Pi Pico for Radio Amateurs
Рис. 6.126: Блок-схема проекта.
Схема подключения проекта показана на рис. 6.127. Соединения между Raspberry Pi Pico и
внешними компонентами следующие:
Raspberry Pi Pico GPIO
Pin number
Connected to
SDA1 4 I2C LCD SDA
SCL1 5 I2C LCD SCL
SDA0
SCL0
GP6
GP7
GP8
1 I2C Radio SDA
2 I2C Radio SCL
9
10
11
Рис. 6.127: Схема проекта.
● 252
CLK Rotary encoder
DT Rotary encoder
SW Rotary encoder
Chapter 6 • Amateur Radio Hardware-based Projects
На рис. 6.128 показан листинг программы (программа: RadioRotary.py). В начале программы
импортируются используемые модули, определяется подключение ЖК-дисплея по протоколу
I2C, и в верхней строке ЖК-дисплея отображается текст TEA5767 FM RADIO. Затем
определяются подключения поворотного энкодера и модуля FM-радио TEA5767. Функции
sinit() и set_freq() аналогичны функциям в предыдущих проектах. Основная программа
выполняется в бесконечном цикле с использованием оператора while. Внутри этого цикла
отслеживаются повороты поворотного энкодера, и частота изменяется на 0,1 МГц при каждом
нажатии энкодера. Полученная частота передается в функцию set_freq(), которая затем
настраивает радиомодуль на эту частоту для приема передач. Перед запуском проекта
убедитесь, что вы подключили антенну и наушники к радиомодулю TEA5767.
#----------------------------------------------------------------#
FM-радио с ЖК-дисплеем и энкодером
#
=================================
#
# Это FM-радио, использующее радиомодуль TEA5767. Модуль
# работает с сигналами I2C SDA и SCL, подключенными к SCL0
# SDA0 Raspberry Pi Pico. Дополнительно подключен поворотный энкодер
# который можно использовать для увеличения или уменьшения частоты
# с шагом 0,1 МГц. Рекомендуется использовать аудиоусилитель
# для повышения уровня сигнала, чтобы можно было подключить
# громкоговоритель к схеме
#
# Author: Dogan Ibrahim
# File
: RadioRotary.py
# Date
: Sept 2021
#------------------------------------------------------------------from machine import I2C, Pin
from pico_i2c_lcd import I2cLcd
import utime
#
# Модуль ЖК-дисплея I2C подключен к SDA1, SCL1
#
i2c_lcd = I2C(id=1,scl=Pin(3),sda=Pin(2),freq=100000)
lcd = I2cLcd(i2c_lcd, 0x27, 2, 16)
#
# Отображение заголовка сообщения
#
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr("TEA5767 FM RADIO")
utime.sleep(3)
buff = [0]*5
● 253
Raspberry Pi Pico for Radio Amateurs
#
# Соединения энкодера
#
CLK = Pin(6, Pin.IN)
# Контакт CLK
DT = Pin(7, Pin.IN)
# Контакт DT
SW = Pin(8, Pin.IN, Pin.PULL_UP)
# Контакт SW
#
# Радиомодуль TEA5767 подключен к SDA0, SCL0
#
i2c = machine.I2C(0, scl=Pin(1), sda=Pin(0), freq=100000)
address = 0x60 # Address
#
# Инициализация TEA5767
#
def init():
buff[0] = 0x80
i2c.writeto(address, bytearray(buff))
utime.sleep(0.2)
#
# Эта функция устанавливает радиостанцию на необходимую частоту.
#
def set_freq(freq):
N = int (4 * (freq * 1000000 + 225000) / 32768)
Nupper = N >> 8
Nlower = N
& 0xFF
buff[0] = Nupper
buff[1] = Nlower
buff[2] = 0xB0
buff[3] = 0x10
buff[4] = 0x00
i2c.writeto (address, bytearray(buff))
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr("freq set to:")
lcd.move_to(0, 1)
lcd.putstr(str(freq)+" MHz")
init()
frequency = 101.4
set_freq(frequency)
● 254
# Начальная частота
Chapter 6 • Amateur Radio Hardware-based Projects
flag = 1
ClkOldState = CLK.value()
# Get CLK state
#
# Получение требуемой частоты. Каждый щелчок поворотного энкодера
# увеличивает или уменьшает частоту на 0,1 МГц
#
while True:
ClkState = CLK.value()
DTState = DT.value()
if ClkState != ClkOldState and ClkState == 1:
if DTState != ClkState:
frequency = frequency + 0.1
else:
frequency = frequency - 0.1
set_freq(frequency)
utime.sleep(0.1)
ClkOldState = ClkState
Рис. 6.128. Программа: RadioRotary.py..
Рис. 6.129 показывает проект, собранный на макетной плате и
настроенный на 101,4 МГц.
Рис. 6.129: Проект, собранный на макетной плате.
Полностью готовое FM-радио на базе Raspberry Pi Pico
1. Работа от батареи
Теперь, когда проект работает независимо от ПК, вы можете захотеть использовать его от
батареи. Пожалуй, самый простой вариант — использовать внешний аккумулятор,
предназначенный для зарядки мобильных телефонов. Это позволит подключить Raspberry Pi
Pico к внешнему аккумулятору с помощью кабеля micro USB.
● 255
Raspberry Pi Pico for Radio Amateurs
2. Автоматическая загрузка
При работе автономно от ПК может потребоваться запуск радиопрограммы сразу после
подачи питания на Raspberry Pi Pico. Механизм автоматической загрузки описан в главе 7 и
повторяется здесь. Все, что нам нужно сделать, это сохранить нашу программу
RadioRotary.py как main.py на Raspberry Pi. Тогда радиопрограмма будет запускаться
автоматически при каждом включении питания на Raspberry Pi Pico.
3. Использование модуля аудиоусилителя
Как описано в предыдущем проекте, перед подключением радиоприемника к
громкоговорителю потребуется модуль аудиоусилителя. В качестве примера можно
использовать аудиоусилитель, показанный на рис. 6.130. Этот усилитель имеет удобный
встроенный регулятор громкости.
Рис. 6.130: Модуль усилителя звука.
4. Схема расположения компонентов на передней панели корпуса радиоприемника
Компоновка передней панели нашего радиоприемника показана на рис. 6.131.
Блок-схема компонентов внутри корпуса показана на рис. 6.132.
Рис. 6.131: Предлагаемая компоновка передней панели.
● 256
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.132: Блок-схема радиоприемника.
6.15 Проект 29: Измерение частоты и коэффициента заполнения ШИМ-сигнала
– отображение на экране
В этом проекте измеряются и отображаются на экране частота и коэффициент заполнения
ШИМ-сигнала. Измеряемые частота и коэффициент заполнения ШИМ-сигнала подаются на порт
GP17 (вывод 22). Убедитесь, что приложенное напряжение не превышает +3,3 В, иначе вы
можете повредить входную цепь вашего Pico.
На рис. 6.133 показан листинг программы (Программа: MeasPWM). Программа измеряет
временные значения Mark (т.е. логическая 1) и Space (т.е. логический 0) входного ШИМ-сигнала в
микросекундах. Затем рассчитываются коэффициент заполнения и частота следующим образом:
Duty cycle (%) = 100 × Mark / (Mark + Space)
Frequency (kHz) = 1000 / (Mark + Space)
#---------------------------------------------------------#
ИЗМЕРЕНИЕ ЧАСТОТЫ И РАБОЧЕГО ВРЕМЕНИ
#
=========================================
#
# В этом проекте на Pico подается ШИМ-сигнал.
# Частота и коэффициент заполнения этого сигнала измеряются и
# отображаются на экране Thonny.
#
# Author: Dogan Ibrahim
● 257
Raspberry Pi Pico for Radio Amateurs
# File
: MeasFreq.py
# Date
: Sept 2021
#-----------------------------------------------------------from machine import Pin
import utime
PWMin = Pin(17, Pin.IN)
# ШИМ вход
while True: # работать вечно
while True:
if PWMin.value() == 1:
# Подожди, пока 0
break
Tmr1Strt = utime.ticks_cpu()
# Запустить таймер 1
while True:
if PWMin.value() == 0:
# Подожди, пока 1
break
Tmr1End = utime.ticks_cpu()
# End
while True:
if PWMin.value() == 1:
# Подожди, пока 0
break
Tmr2End = utime.ticks_cpu()
# End
Mark = utime.ticks_diff(Tmr1End, Tmr1Strt)
Space = utime.ticks_diff(Tmr2End, Tmr1End)
duty = 100.0 * Mark / (Mark + Space)
freqkHz = 1000.0 / (Mark + Space)
print("Duty Cycle = %5.2f" % duty)
print("Frequency (kHz) = ", freqkHz, "\n")
utime.sleep(2)
Рис. 6.133: Программа: MeasPWM..
Пример вывода программы показан на рис. 6.134.
Рис. 6.134: Пример вывода.
● 258
Chapter 6 • Amateur Radio Hardware-based Projects
6.16 Проект 30: Измерение частоты и рабочего цикла сигнала ШИМ –
ЖК-дисплей
В этом проекте частота и рабочий цикл сигнала ШИМ измеряются и отображаются на
ЖК-дисплее. Сигнал ШИМ, частоту и рабочий цикл которого необходимо измерить, подается на
порт GP17 (контакт 22), как и в предыдущем проекте. Убедитесь, что подаваемое напряжение не
превышает +3,3 В, иначе вы можете повредить входную схему вашего Pico.
На рис. 6.135 показан листинг программы (program: MeasPWMLcd). Программа измеряет
тайминги Mark (т. е. логическая 1) и Space (т. е. логический 0) входного сигнала ШИМ в
микросекундах. Затем рабочий цикл и частота рассчитываются следующим образом:
Duty cycle (%) = 100 × Mark / (Mark + Space)Frequency (kHz) = 1000 / (Mark + Space)
#---------------------------------------------------------# ИЗМЕРЕНИЕ ЧАСТОТЫ И РАБОЧЕГО ЦИКЛА — ВЫХОД НА ЖК-дисплей
# ==========================================================
#
# В этом проекте к Pico применяется ШИМ.
# Частота и рабочий цикл этого сигнала измеряются и
# отображаются на ЖК-дисплее.
#
# Author: Dogan Ibrahim
# File
: MeasFreq.py
# Date
: Sept 2021
#-----------------------------------------------------------from machine import Pin, I2C
from pico_i2c_lcd import I2cLcd
import utime
#
# Модуль ЖК-дисплея I2C подключен к SDA1, SCL1
#
i2c_lcd = I2C(id=1,scl=Pin(3),sda=Pin(2),freq=100000)
lcd = I2cLcd(i2c_lcd, 0x27, 2, 16)
PWMin = Pin(17, Pin.IN)
# Вход ШИМ-сигнала
while True: # работать вечно
while True:
if PWMin.value() == 1:
# Подождите, пока 0
break
Tmr1Strt = utime.ticks_cpu()
# Запустить таймер 1
if PWMin.value() == 0:
# Подождите, пока 1
while True:
● 259
Raspberry Pi Pico for Radio Amateurs
break
Tmr1End = utime.ticks_cpu()
# End
while True:
if PWMin.value() == 1:
# Подождите, пока 0
break
Tmr2End = utime.ticks_cpu()
# End
Mark = utime.ticks_diff(Tmr1End, Tmr1Strt)
Space = utime.ticks_diff(Tmr2End, Tmr1End)
duty = 100.0 * Mark / (Mark + Space)
freqkHz = 1000.0 / (Mark + Space)
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr("Duty(%)=" + str(duty)[:5])
lcd.move_to(0, 1)
lcd.putstr("F(kHz) =" + str(freqkHz)[:7])
utime.sleep(2)
Рис. 6.135: Программа: MeasPWMLcd..
6.17 Интерфейс Bluetooth для Raspberry Pi Pico
Существуют приложения, где радиолюбитель может захотеть получить удаленный доступ к
оборудованию, например, через функцию Bluetooth мобильного телефона.
У Raspberry Pi Pico нет встроенного модуля Bluetooth. Нам необходимо использовать
внешний модуль Bluetooth, чтобы Pico мог взаимодействовать с другими устройствами через
Bluetooth. Одним из вариантов может быть использование компьютера Raspberry Pi.
Возможно, более дешевым вариантом является использование последовательного модуля
Bluetooth, такого как HC-06. В следующем разделе мы разработаем проект и научимся
подключать недорогой модуль Bluetooth типа HC-06 к нашему Raspberry Pi Pico.
6.17.1 Проект 31: Управление светодиодом со смартфона с помощью Bluetooth
В этом проекте мы будем отправлять команды по Bluetooth со смартфона для управления
светодиодом, подключенным к Raspberry Pi Pico (вы можете легко заменить светодиоды реле,
например, чтобы можно было дистанционно управлять электрическими устройствами). В этом
проекте допустимыми командами являются:
L1
L0
Включить светодиод
Выключить светодиод
Модуль Bluetooth HC-06
HC-06 — это недорогой и популярный 4-контактный модуль с последовательным
управлением, имеющий следующие контакты (см. рис. 6.136):
● 260
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.136: Модуль Bluetooth HC-06.
HC-06 — это модуль с последовательным управлением, обладающий следующими
основными характеристиками:
•
•
•
•
•
•
•
•
•
Работает от +3,3 В до +6 В
Непарный ток 30 мА (согласованный ток 10 мА)
Встроенная антенна
Диапазон частот: 2,40 ГГц – 2,48 ГГц
Уровень мощности: +6 дБм
Стандартная скорость связи: 9600 бод, 8 бит данных, без контроля четности, 1 стоповый бит
Зона покрытия сигнала: 30 футов
Функция безопасности: аутентификация и шифрование
Режим модуляции: частотная манипуляция Гаусса
На рис. 6.137 показана блок-схема проекта.
Рис. 6.137: Блок-схема проекта.
На рис. 6.138 показана принципиальная схема проекта. Контакты RXD и TXD модуля Bluetooth
подключены к контактам UART 0 GP0 (TX) и GP1 (RX) Raspberry Pi Pico соответственно.
Светодиод подключен к контакту GP16 (контакт 21) через токоограничивающий
резистор 470 Ом.
● 261
Raspberry Pi Pico for Radio Amateurs
Рис. 6.138: Схема проекта.
Листинг программы проекта показан на рис. 6.139 (программа: BlueLED). В начале
программы аппаратный интерфейс UART устанавливается на скорость передачи данных
9600 бод (т.е. скорость по умолчанию для HC-06), светодиод настраивается как выход и
выключается. Остальная часть программы выполняется в бесконечном цикле. Внутри этого
цикла данные (команды) принимаются от устройства Bluetooth с помощью вызова функции
readline. Считанные данные сохраняются в буфере списка. Затем программа управляет
светодиодом на основе полученной команды. Например, L1 включает светодиод, L0
выключает его и так далее.
#---------------------------------------------------------#
СВЯЗЬ ПО BLUETOOTH
#
===================
#
# В этом проекте последовательный модуль Bluetooth типа HC-06
# и светодиод подключены к Raspberry Pi Pico.
# Светодиод управляется путем отправки команд
# со смартфона, совместимого с Bluetooth.
#
# Author: Dogan Ibrahim
# File
: BlueLED.py
# Date
: Sept 2021
#-----------------------------------------------------------from machine import Pin, UART
import utime
uart = UART(0, baudrate=9600,rx=Pin(1),tx=Pin(0))
LED = Pin(16, Pin.OUT)
LED.value(0)
● 262
Chapter 6 • Amateur Radio Hardware-based Projects
#
# Основной цикл программы. Получайте команду и управляйте светодиодом
#
while True:
buf = uart.readline()
# Чтение данных
dat = buf.decode('UTF-8')
# Декодирование
if dat[0] == 'L' and dat[1] == '1':
# L1?
LED.value(1)
elif dat[0] == 'L' and dat[1] == '0':
LED.value(0)
# Светодиод горит
# L0?
# Светодиод ВЫКЛ.
Рис. 6.139: Программа: BlueLED.
.
Тестирование программы
Программу можно протестировать, используя смартфон Android для отправки команд через
интерфейс связи Bluetooth. В Play Store есть множество бесплатных программ для связи по
Bluetooth. Автор выбрал программу под названием BluetoothController от mightyIT
(it@memighty.com), как показано на рис. 6.140. Вам следует установить это приложение на свой
смартфон Android, чтобы отправлять команды на плату разработки.
Рис. 6.140: Приложение «Контроллер Bluetooth».
Последовательность действий для тестирования приложения следующая:
•
•
•
•
Соберите проект.
Загрузите программу на ваш Raspberry Pi Pico.
Активируйте приложение «Контроллер Bluetooth» на вашем мобильном телефоне.
Приложение начнет поиск ближайших устройств Bluetooth. Нажмите на HC-06,
как только оно отобразится
.
на экране смартфона (возможно, потребуется
выполнить поиск устройств).
• Вам будет предложено ввести пароль для сопряжения телефона
с платой разработки. Введите пароль по умолчанию, например, 1234.
● 263
Raspberry Pi Pico for Radio Amateurs
• Запустите приложение Bluetooth на своем смартфоне. Нажмите на полукруг
со стрелкой в правом верхнем углу экрана, чтобы подключиться к HC-06.
• При установлении соединения с HC-06 в правом верхнем углу экрана должна
появиться зеленая точка. Также в левом верхнем углу экрана должен
отображаться HC-06 с его адресом (например, HC-06 [98:D3:31:FB:5E:B6]).
• Чтобы включить светодиод, введите команду L1 и нажмите «Отправить ASCII».
Светодиод должен загореться. Чтобы выключить светодиод, введите команду L0.
На рис. 6.141 показан пример экрана.
Рис. 6.141: Пример команды для включения светодиода.
Мы можем изменить программу на рис. 6.139, отправив подтверждение на смартфон при
изменении состояния светодиода. Необходимые изменения показаны ниже:
while True:
buf = uart.readline()
LED.value(1)
# Чтение данных
# Декодирование
# L1?
# Светодиод включен
uart.write("LED is ON")
# Отправка подтверждения
dat = buf.decode('UTF-8')
if dat[0] == 'L' and dat[1] == '1':
elif dat[0] == 'L' and dat[1] == '0':
LED.value(0)
uart.write("LED is OFF")
# L0?
# Светодиод выключен
# Отправка подтверждения.
Например, как показано на рис. 6.142, после отправки команды L1 на экране отображается
сообщение LED is ON.
● 264
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.142: Пример отображения с подтверждением.
6.18 Проект 32: Безопасность станции
Если в доме есть семья с детьми, возможно, вам следует ограничить доступ в комнату
радиостанции по соображениям безопасности. В этом проекте мы разработаем систему
безопасности на основе RFID для управления выходным устройством, например, реле,
зуммером, светодиодом и т. д. В качестве реле может выступать, например, реле
разблокировки двери или главное реле питания станции. Управлять реле смогут только лица,
имеющие действительную RFID-карту.
В этом проекте используется популярный RFID-контроллер RC522 (см. рис. 6.143).
Это недорогой RFID-модуль на основе микросхемы MFRC522. Модуль работает на
частоте 13,56 МГц и обладает следующими характеристиками:
•
•
•
•
•
•
+3.3 V питание
13-26 mA ток потребления
3 cm диапозон считывания
Интерфейс SPI для подключения к микроконтроллеру
Скорость передачи данных 10 Мбит/с
Размер: 60 × 39 мм
Блок считывания состоит из радиочастотного модуля и антенны, генерирующей
высокочастотное электромагнитное поле. Метка обычно представляет собой пассивное
устройство, то есть не содержит батареи. Вместо этого она содержит микрочип, который
хранит и обрабатывает информацию, и антенну для приема и передачи сигнала. Для
считывания информации, закодированной в метке, она размещается в непосредственной
близости от считывателя (нет необходимости находиться в прямой видимости
считывателя). Считыватель генерирует электромагнитное поле, которое заставляет
электроны двигаться через антенну метки и, следовательно, питать чип.
● 265
Raspberry Pi Pico for Radio Amateurs
Питаемый чип внутри метки затем отвечает, отправляя сохраненную информацию обратно
считывателю в виде радиосигнала.
Рис. 6.143: Плата контроллера RFID RC522.
Расположение выводов модуля RC522 показано на рис. 6.144.
Рис. 6.144: Расположение выводов модуля RC522.
RX/SDA/SS — это входной сигнал для шины SPI (также используется как
последовательный ввод данных при включенном интерфейсе I2C).
SCK — это тактовый сигнал, предоставляемый ведущим устройством шины SPI.
MOSI — это вход SPI для модуля RC522.
TX/SCL/MISO — это выход ведомого устройства при использовании шины SPI и
используется как тактовый сигнал при включенном интерфейсе I2C.
IRQ — это вывод прерывания, который можно использовать для оповещения
микроконтроллера о приближении RFID-метки к считывателю.
GN — это вывод земли
RST — это пин сброса. Считыватель сбрасывается, когда этот пин переходит в
низкое состояние. Для нормальной работы должен быть подключен к +3,3 В
VCC — питание +3,3 В.
● 266
Chapter 6 • Amateur Radio Hardware-based Projects
На рис. 6.145 показана блок-схема проекта. В данном проекте в качестве выходного
устройства используется активный зуммер.
Рис. 6.145: Блок-схема проекта.
Raspberry Pi Pico имеет несколько выводов шины SPI. В этом проекте между считывателем
RFID-карт и Raspberry Pi Pico выполнены следующие соединения:
Raspberry Pi Pico pin
GP2 (4)
GP3 (5)
GP4 (6)
GP0 (1)
GP1 (2)
RC522 pin
SCK (7)
MOSI (6)
MISO (5)
RST (2)
SS (8)
Соединения между Raspberry Pi Pico и считывателем RFID-карт показаны на принципиальной
схеме на рис. 6.146. В этом проекте в качестве выходного устройства подключен зуммер.
Когда авторизованная RFID-метка подносится к считывателю карт, зуммер издает звуковой
сигнал в течение 5 секунд, а затем выключается. При необходимости это поведение можно
легко изменить.
Рис. 6.146: Схема проекта.
● 267
Raspberry Pi Pico for Radio Amateurs
На рис. 6.147 показан листинг программы (программа: RFID). Стандартные RFID-карты
ISO/IEC14443-A имеют UID длиной 4 байта, поэтому существует 4,2 миллиарда различных
UID. Хотя RFID-карты могут хранить данные, в этом проекте нас интересует только UID-код
нашей карты. Когда карта подносится к считывателю, считывается 4-байтовый UID карты,
который сравнивается с ожидаемым жестко закодированным в программе номером UID. Если
два номера совпадают, устройство, подключенное к выходу, активируется (в этом примере
активируется зуммер) на 5 секунд. Если устройство, например, является дверным реле, дверь
откроется!
Программа, используемая в этом проекте, использует библиотеку mfrc522.py, разработанную
Стефаном Вендлером, который является правообладателем этой библиотеки (см. ссылку:
https://github.com/danjperron/micropython-mfrc522)
Программа mfrc522.py включена в .zip-архив для этой книги. Перед использованием
программы, показанной на рис. 6.147, необходимо скопировать эту программу на ваш
Raspberry Pi Pico. В сессии Thonny нажмите «File » → «Open» и найдите файл mfrc522.py.
Затем сохраните файл на вашем Raspberry Pi Pico, убедившись, что расширение файла .py
присутствует в имени файла перед сохранением.
Программа, показанная на рис. 6.147, считывает UID-номер вашей RFID-метки. Если метка
авторизована, срабатывает звуковой сигнал. 4-байтовый десятичный UID-номер карты автора
был 49, 49, 57, 46.
Вы можете найти UID-номер своей собственной RFID-метки, удалив символы комментария
(###) в начале оператора print в программе. Затем используйте эти числа в операторе if для
авторизации вашей RFID-метки. Вы можете авторизовать несколько меток, если измените
оператор if или добавите дополнительные операторы if.
#---------------------------------------------------------#
СЧИТЫВАТЕЛЬ RFID-КАРТ
#
=======================
#
# В этом проекте считыватель RFID-карт типа RC522 подключен
# к Raspberry Pi Pico. Программа демонстрирует, как можно считать
# RFID-карту. Считывается только UID карты, и если это
# авторизованная карта, то зуммер, подключенный к GP13
# Raspberry Pi Pico, срабатывает на 5 секунд. Этот зуммер
# предназначен только для демонстрационных целей и при
# необходимости может быть заменен реле.
#
# Author: Dogan Ibrahim
# File
: RFID.py
# Date
: Sept 2021
#-----------------------------------------------------------from machine import Pin
● 268
Chapter 6 • Amateur Radio Hardware-based Projects
from mfrc522 import MFRC522
import utime
Buzzer = Pin(13, Pin.OUT)
Buzzer.value(0)
reader = MFRC522(spi_id=0,sck=2,miso=4,mosi=3,cs=1,rst=0)
while True:
reader.init()
(stat, tag_type) = reader.request(reader.REQIDL)
if stat == reader.OK:
(stat, uid) = reader.SelectTagSN()
###print(uid)
if uid[0]==49 and uid[1]==49 and uid[2]==57 and uid[3]==46:
Buzzer.value(1)
utime.sleep(5)
Buzzer.value(0)
Рис. 6.147: Программа:RFID.py.
.
На рис. 6.148 показан проект, собранный на макетной плате.
Рис. 6.148: Проект, собранный на макетной плате.
● 269
Raspberry Pi Pico for Radio Amateurs
6.19 Проект 33: Генерация точных прямоугольных сигналов с
использованием конечных автоматов Raspberry Pi Pico
В этом проекте мы будем использовать конечные автоматы Raspberry Pi Pico (SM) для
генерации точных прямоугольных сигналов в диапазоне от 2 кГц до более 100 МГц.
RP2040 содержит два программируемых блока IO (PIO) с четырьмя конечными автоматами в
каждом для управления выводами GPIO и передачи данных. Каждый блок PIO имеет одну
память инструкций с 32 инструкциями. Каждый конечный автомат также может управлять
любым из выводов GPIO на Pico. Программирование экземпляра PIO осуществляется с
помощью языка ассемблера, а программу можно написать с использованием редактора
Thonny. Конечные автоматы поддерживают девять инструкций:
•
•
•
•
•
•
•
•
•
in()
out()
push()
pull()
mov()
irq()
wait()
jmp()
set()
На рис. 6.149 показан листинг программы (program:SquareSM.py). В начале
программы импортируются необходимые библиотеки. Функция, выполняемая в
программе, называется square и ей предшествует декоратор, который сообщает
интерпретатору Python, что далее следуют операторы языка ассемблера. Операторы
set(pins, 1) и set(pins, 0) устанавливают и сбрасывают указанный вывод. Функции
wrap_target() и wrap() создают цикл. Пользователю предлагается ввести
требуемую частоту и номер вывода, на котором будет генерироваться частота.
Минимальное значение частоты — 2 кГц. Конечный автомат инициализируется
следующим оператором:
sm = rp2.StateMachine(0, square, freq=f*2, set_base=Pin(p))
где используется конечный автомат 0, freq — требуемая частота, а set_base —
номер контакта, подключенного к этому конечному автомату.
Операторы m.active(1) запускают конечный автомат, а операторы m.active(0)
останавливают его.
#=======================================================
#
ПРЯМОУГОЛЬНЫЙ СИГНАЛ
#
=======================
#
# Эта программа использует конечные автоматы Raspberry Pi Pico
# для создания точных прямоугольных волновых сигналов в диапазоне
# от 2 кГц до 133 МГц
#
● 270
Chapter 6 • Amateur Radio Hardware-based Projects
# Author: Dogan Ibrahim
# File
: SquareSM.py
# Date
: Sept 2021
#========================================================
from machine import Pin
from rp2 import PIO, StateMachine, asm_pio
import utime
@asm_pio(set_init=PIO.OUT_LOW)
def square():
wrap_target()
set(pins, 1)
set(pins, 0)
wrap()
f = 0
while f < 2000:
f = int(input("Enter frequency in Hz (Min 2000): "))
if f < 2000:
print("Minimum frequency is 2000 Hz...")
print("")
p = int(input("Enter pin number: "))
sm = rp2.StateMachine(0, square, freq=f*2, set_base=Pin(p))
sm.active(1)
utime.sleep(10)
sm.active(0)
Рис. 6.149: Программа:SquareSM.py.
Дополнительную информацию о конечном автомате Raspberry Pi и его командах можно
получить по следующей ссылке:
https://dernulleffekt.de/doku.php?id=raspberrypipico:pico_pio
6.20 Проект 34: Использование Wi-Fi с Raspberry Pi Pico – Управление
светодиодом со смартфона
Как радиолюбители, мы можем управлять удаленными устройствами через домашний Wi-Fi
роутер с помощью смартфонов. Например, мы можем захотеть удаленно управлять реле,
светодиодами, двигателями и т. д. с помощью смартфонов.
В этом проекте мы будем отправлять команды через домашний Wi-Fi-роутер со смартфона для
управления светодиодом (светодиод можно заменить реле, например, для управления
устройством, подключенным к Raspberry Pi Pico). Допустимые команды: (команда должна
завершаться символом новой строки):
● 271
Raspberry Pi Pico for Radio Amateurs
LON
LOFF
Включить светодиод
Выключить светодиод
Raspberry Pi Pico не имеет встроенного модуля Wi-Fi, и поэтому его нельзя подключить к сети
Wi-Fi без использования внешнего модуля Wi-Fi. Пожалуй, самый простой и дешевый способ
обеспечить Pico возможностью подключения по Wi-Fi — это использование платы процессора
ESP-01. Это крошечная плата (см. рис. 6.150) размером всего 2,7 × 1,2 см, основанная на
процессоре ESP8266 и стоящая около 3 долларов США. ESP-01 обладает следующими
характеристиками:
•
•
•
•
Рабочее напряжение: +3,3 В
Интерфейс: использование простых AT-команд через последовательный порт/UART
Встроенный стек протоколов TCP/IP. 802.11 b/g/n
Не требуется никаких внешних компонентов
Рис. 6.150: Плата процессора ESP-01.
ESP-01 взаимодействует с главным процессором через контакты последовательного
порта TX и RX. Это 8-контактная плата со следующими названиями контактов:
питание +3,3 В
VCC:
земля
GND:
GPIO0: Контакт I/O. Для нормальной работы должен быть подключен
к +3,3 В, а для загрузки прошивки в микросхему — к GND.
GPIO2:
RST:
CH_PD:
TX:
RX:
Контакт
Контакт
Контакт
Контакт
Контакт
ввода/вывода общего назначения
сброса. Должен быть подключен к +3,3 В.
включения. Должен быть подключен к +3,3 В.
последовательного вывода
последовательного ввода
Контакты ESP-01 несовместимы со стандартными макетными платами, и для установки платы
на макетную плату потребуется адаптер (см. рис. 6.151).
● 272
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.151: Адаптер для макетной платы ESP-01.
На рис. 6.152 показана блок-схема проекта.
Рис. 6.152: Блок-схема проекта.
На рис. 6.153 показана принципиальная схема проекта. Для связи с ESP-01 используются
контакты UART 0 TX и RX платы Raspberry Pi Pico.
● 273
Raspberry Pi Pico for Radio Amateurs
Рис. 6.153: Схема проекта.
На рис. 6.154 показан листинг программы (программа: PicoWiFi). Внутри подпрограммы setup
скорость последовательной связи устанавливается на 115200 бод, что является стандартной
скоростью передачи данных для ESP-01, а светодиод настраивается как выход и
выключается. Вызывается функция ConnectToWiFi для подключения к локальному
Wi-Fi-роутеру. AT-команды используются для настройки ESP-01 для подключения к
Wi-Fi-роутеру.
Остальная часть программы выполняется в бесконечном цикле, сформированном с помощью
оператора while. Внутри этого цикла данные принимаются со смартфона, и светодиод
управляется соответствующим образом. Команды LON и LOFF включают и выключают
светодиод соответственно. Пакет данных принимается со смартфона с помощью оператора
readline и его функции. Функция find ищет подстроку в строке и возвращает ненулевое
значение, если подстрока найдена. Причина использования функции find заключается в том,
что данные, полученные с мобильного устройства, имеют следующий формат: +ID0,n: data
(например, +ID0,3:LON), где 0 — идентификатор канала, а n — количество полученных
символов. Используя функцию find, мы можем легко найти строки LON или LOFF в
полученном пакете данных.
Функция ConnectToWiFi отправляет следующие команды на ESP-01для подключения к Wi-Fi:
AT+RST
AT+CWMODE
AT+CWJAP
AT+CIPMUX
AT+CIFSR
AT+CIPSTART
● 274
Сброс ESP-01
Установка режима ESP-01
Установка имени и пароля SSID Wi-Fi
Установка режима подключения
Установка режима подключения TCP или UDP, целевого IP-адреса и порта
- номер (здесь используется UDP с номером порта 5000. Целевой IP-адрес
устанавливается на "0.0.0.0", чтобы любое устройство могло отправлять
данные, пока используется порт 5000 (вы можете изменить это на IP-адрес
вашего смартфона, чтобы получать данные только с телефона).
Chapter 6 • Amateur Radio Hardware-based Projects
#---------------------------------------------------------#
ИСПОЛЬЗОВАНИЕ WI-FI
#
=====================
#
# В этом проекте микросхема ESP-01 подключена к Raspberry Pi
# Pico. Эта микросхема используется для подключения Pico к Wi-Fi.
#
# Author: Dogan Ibrahim
# File
: PicoWiFi.py
# Date
: Sept 2021
#-----------------------------------------------------------from machine import Pin, UART
import utime
uart = UART(0, baudrate=115200,rx=Pin(1),tx=Pin(0))
LED = Pin(16, Pin.OUT)
LED.value(0)
#
# Отправка AT-команд на ESP-01 для подключения к локальной сети Wi-F
#
def ConnectToWiFi():
uart.write("AT+RST\r\n")
utime.sleep(5)
uart.write("AT+CWMODE=1\r\n")
utime.sleep(1)
uart.write('''AT+CWJAP="BTHomeSpot-XNH","49345xyzpq"\r\n''')
utime.sleep(5)
uart.write("AT+CIPMUX=0\r\n")
utime.sleep(3)
uart.write('''AT+CIPSTART="UDP","0.0.0.0",5000,5000,2\r\n''')
utime.sleep(3)
ConnectToWiFi()
#
# Основная программа loop
#
while True:
buf = uart.readline()
# Чтение данных
if buf:
dat = buf.decode('UTF-8')
# Декодирование
● 275
Raspberry Pi Pico for Radio Amateurs
n = dat.find("LON")
# Включает LON?
if n > 0:
LED.value(1)
n = dat.find("LOFF")
# Светодиод включен
# Includes OFF?
if n > 0:
LED.value(0)
# Светодиод выключен
Рис. 6.154: Программа: PicoWiFi..
Обратите внимание, что после каждой команды используются небольшие задержки.
Команда AT+CWJA требует большей задержки. Программу можно легко модифицировать
таким образом, чтобы убрать задержки и проверить ответы от ESP-01. Таким образом, как
только будет получен правильный ответ, программа сможет продолжить работу. Возможно,
вам потребуется выполнить аппаратную перезагрузку ESP-01, выключив и снова включив
его, прежде чем запускать программу.
Тестирование программы
Программу можно легко оценить с помощью программы PacketSender (см. рис. 6.155) на ПК
или с помощью смартфона после установки UDP-приложений.
Рис. 6.155: Использование PacketSender для тестирования программы.
Перед началом тестирования на смартфоне Android необходимо установить приложение
UDP-сервера. В Play Store доступно множество бесплатных приложений UDP. В этом проекте
используется виджет UDP/TCP от K.J.Mas, показанный на рис. 6.156.
● 276
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.156: Приложение UDP/TCP Widget для Android.
Последовательность действий для тестирования программы следующая:
•
•
•
•
Соберите схему
Загрузите программу на свой Raspberry Pi Pico
Запустите приложение UDP/TCP Widget на своем мобильном телефоне.
Щелкните значок шестеренки и установите протокол на UDP, IP-адрес на IP-адрес вашего
Raspberry Pi Pico (192.168.1.160 на Pico автора) и установите порт на 5000, как показано на
рис. 6.157.
Рис. 6.157: Настройка приложения.
• Щелкните пункт меню «MESSAGE» и выберите «Text (UTF-8)» в качестве
формата, затем введите команду LON, чтобы включить светодиод. Выберите
LF в качестве терминатора и нажмите символ OK (символ галочки), как
показано на рис. 6.158.
● 277
Raspberry Pi Pico for Radio Amateurs
• Теперь нажмите кнопку SEND (Рис. 6.159), чтобы отправить команду на Raspberry Pi Pico. В
верхней части экрана вашего Android-устройства временно должно отобразиться сообщение
«Пакет отправлен».
Рис. 6.158: Команда для включения светодиода.
Рис. 6.159: Нажмите (SEND), чтобы отправить команду.
Обратите внимание, что IP-адрес ESP-01 можно получить, просканировав все устройства в
локальном Wi-Fi-роутере. Например, для просмотра IP-адресов всех устройств, подключенных к
вашему роутеру, можно использовать приложение для Android под названием Who Uses My WiFi
– NetworkScanner от Phuongpn. ESP-01 указан, как показано на рис. 6.160 (IP: 192.168.1.160),
подименем Espressif.
● 278
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.160: Определение IP-адреса ESP-01.
6.21 Проект 35: Модуль аудиоусилителя с поворотным энкодером для
регулировки громкости
Одна из проблем регуляторов громкости в аудиоусилителях заключается в том, что
потенциометр является источником шумовых помех (шуршания), и со временем
становится трудно плавно регулировать громкость с помощью потенциометра. В этом
проекте мы будем использовать модуль аудиоусилителя с поворотным энкодером для
регулировки громкости.
В данном проекте используется аудиоусилитель AudioAmp click (рис. 6.161), разработанный и
произведенный компанией MikroElektronika (www.mikroe.com). Это монофонический
аудиоусилитель, основанный на микросхеме усилителя мощности Texas Instruments
LM48100Q-Q1 Boomer Mono мощностью 1,3 Вт. Модуль имеет один 3,5-мм входной разъем и
расположенные рядом с ним винтовые клеммы для подключения выходных проводов к
пассивному динамику. Он имеет два аудиовхода, которые можно
микшировать/мультиплексировать на выход устройства. Каждый входной тракт имеет свой
собственный независимый 32-ступенчатый цифровой регулятор громкости. Микшер, регулятор
громкости и выбор режима работы устройства управляются через интерфейс mikroBUS I2C.
Еще одной важной особенностью LM48100Q является функция обнаружения неисправностей.
Она отслеживает состояние нагрузки, защищая устройство при коротком замыкании, а также
обнаруживает обрыв цепи. AudioAmp Click может работать от источника питания 3,3 В или 5 В.
Также имеется дополнительная перемычка для выбора адреса I2C.
Рис. 6.161: Модуль AudioAmp Click.
В этом проекте мы будем использовать поворотный энкодер для изменения
32-ступенчатой цифровой регулировки громкости усилителя. Поворот поворотного
энкодера на один щелчок изменит громкость на одну ступень. Схема модуля усилителя
показана на рис. 6.162.
● 279
Raspberry Pi Pico for Radio Amateurs
Рис. 6.162: Схема усилительного модуля.
Связь с микроконтроллером осуществляется через интерфейс I2C. Используются следующие
выводы усилительного модуля:
Pin
Description
1,2,3,4,5,6
No connection
7
+3.3 V
8 GND
9 GND
10
+5 V (not used)
11 SDA
12 SCL
13,14 No connection
15
INT (fault)
16
No connection
● 280
Chapter 6 • Amateur Radio Hardware-based Projects
На рис. 6.163 показана блок-схема проекта.
Схема подключения проекта показана на рис. 6.164. Интерфейс между внешними
компонентами и Raspberry Pi Pico следующий:
Raspberry Pi Pico
Device
GP6 (9)
CLK rotary encoder
GP7 (10)
DT rotary encoder
GP8 (11)
SW rotary encoder
GND (3) GND
+3.3 V (36)
+3.3 V
SDA1 (4)
SCL1 (5)
GND (8)
+3.3 V (36)
SDA AudioAmp click (11)
SCL AudioAmp click (12)
GND (8)
+3.3 V (7)
Рис. 6.164: Схема проекта.
● 281
Raspberry Pi Pico for Radio Amateurs
На рис. 6.165 показан листинг программы (Программа: RotaryVolume).В начале программы
определяется интерфейс I2C между модулем аудиоусилителя и Raspberry Pi Pico.
#----------------------------------------------------------------# АУДИОУСИЛИТЕЛЬ С РЕГУЛИРОВКОЙ ГРОМКОСТИ С ЭНКОДЕРОМ
# ==========================================================
#
# В этом проекте используется модуль аудиоусилителя.
# Регулировка громкости усилителя осуществляется цифровым
# способом. Для пошагового изменения громкости при каждом щелчке используется
# поворотный энкодер. В этом проекте используется только вход 1.
#
# Author: Dogan Ibrahim
# File
: RotaryVolume.py
# Date
: Sept 2021
#------------------------------------------------------------------from machine import I2C, Pin
import utime
buff = [0]*2
ModeControl = 0
# Адрес управления режимом
VolumeControl1 = 0x03
# Адрес управления громкостью 1
#
# Модуль I2C AudioAmp подключен к SDA1, SCL1
#
i2c = I2C(id=1,scl=Pin(3),sda=Pin(2),freq=100000)
address = 0x7C
#
# Соединения поворотного энкодера
#
CLK = Pin(6, Pin.IN)
# CLK pin
DT = Pin(7, Pin.IN)
# DT pin
SW = Pin(8, Pin.IN, Pin.PULL_UP)
# SW pin
#
# Установите начальную громкость на низкое значение
#
vol1 = 0x65
buff[0] = VolumeControl1
buff[1] = vol1
i2c.writeto(address, bytearray(buff))
utime.sleep(1)
● 282
# Начальная громкость
Chapter 6 • Amateur Radio Hardware-based Projects
buff[0] = ModeControl
# Управление режимом
buff[1] = 0x14
# Выберите IN1
i2c.writeto(address, bytearray(buff))
# Отправка на I2C
utime.sleep(1)
ClkOldState = CLK.value()
# Получить состояние CLK
#
# Получите необходимый шаг регулировки громкости. Каждый щелчок
# поворотного энкодера увеличивает или уменьшает регулятор громкости на 1 шаг.
#
while True:
ClkState = CLK.value()
DTState = DT.value()
if ClkState != ClkOldState and ClkState == 1:
if DTState != ClkState:
vol1 = vol1 + 1
if vol1 > 0x7F:
vol1 = 0x7F
buff[0] = VolumeControl1
buff[1] = vol1
i2c.writeto(address, bytearray(buff))
utime.sleep(0.1)
else:
vol1 = vol1 - 1
if vol1 < 0x60:
vol1 = 0x60
buff[0] = VolumeControl1
buff[1] = vol1
i2c.writeto(address, bytearray(buff))
utime.sleep(0.1)
buff[0] = ModeControl
# Управление режимами
buff[1] = 0x14
# Выберите IN1
i2c.writeto(address, bytearray(buff))
utime.sleep(0.1)
ClkOldState = ClkState
Рис. 6.165: Программа:RotaryVolume.
Адрес I2C по умолчанию для модуля усилителя — 0x7C. Затем определяется
интерфейс между поворотным энкодером и Raspberry Pi. Как показано в таблице
6.4, модуль усилителя LM48100Q управляется с помощью 4 регистров. В этом
проекте мы будем использовать только вход 1. Важные регистры, которые мы будем
использовать, — это регистр модуляции (адрес 0) и регистр управления громкостью
(адрес 3).
● 283
Raspberry Pi Pico for Radio Amateurs
Регистр модуляции должен быть установлен следующим образом:
B4: Этот бит должен быть установлен в 1 для включения усилителя.
B2: Этот бит должен быть установлен в 1 для включения входа 1.
Регистр регулировки громкости состоит из 32 шагов (от 0 до 31), где каждый шаг вверх
соответствует большей громкости. Значение по умолчанию для регулировки громкости равно
0x60, что соответствует нулевой громкости. Его максимальное значение равно 0x7F, что
соответствует максимальной громкости 32-го шага:
01143210
Где «4321» — двоичные биты, соответствующие значениям 32-го шага регулировки громкости,
при этом 01100000 — минимальная громкость (шаг 0), а 0111111 — максимальное значение
(шаг 32).
В начале программы значение по умолчанию для регулировки громкости устанавливается
равным 0x65 с помощью следующего кода. Затем громкость звука изменяется ступенчато при
каждом щелчке вала поворотного энкодера:
vol1 = 0x65
buff[0] = VolumeControl1
buff[1] = vol1
i2c.writeto(address, bytearray(buff))
utime.sleep(1)
Таблица 6.4: Регистры управления усилителем LM48100Q.
На рис. 6.166 показан проект, собранный на макетной плате.
● 284
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.166: Проект, собранный на макетной плате.
Примечание: Проект усилителя, представленный в этом разделе, легко может
быть использован с проектом Pico FM Radio, описанным в разделе 6.11.
6.22 Проект 36: Декодер азбуки Морзе
Азбука Морзе до сих пор используется многими радиолюбителями. Хотя расшифровка кода
вручную, на слух, гораздо интереснее, многие радиолюбители предпочитают использовать
компьютер для расшифровки кода и его отображения на ЖК-дисплее или экране
компьютера.
В разделе 6.9 мы научились генерировать азбуку Морзе с помощью Raspberry Pi Pico. Там
проекты были посвящены переводу английского текста в азбуку Морзе и последующей
отправке кода на зуммер, подключенный к Pico. Мы также научились генерировать
случайный код для обучения.
В этом разделе мы разработаем проект декодера азбуки Морзе, который будет принимать
звуковой код через микрофон, а затем переводить код в текст и отображать его на экране в
реальном времени. Программа автоматически подстраивается под скорость передачи кода.
Напомним, что скорость передачи азбуки Морзе следующая:
•
•
•
•
•
Dit: 1 единица
Dah: 3 единиц
Интервал между дитом и дахом: 1 единица
Интервал между символами слова: 3 единицы
Интервал между словами: 7 единиц
● 285
"dit" (•)
"dah" (—)
Raspberry Pi Pico for Radio Amateurs
Скорость передачи азбуки Морзе определяется количеством слов в минуту, которые можно
передать или принять. На большинстве экзаменов для радиолюбителей от кандидатов
ожидается передача и прием не менее 12 слов в минуту.
В качестве стандартного слова при расчете скорости используется слово PARIS. Это слово
состоит из 50 единиц времени:
P:
A:
R:
I:
S:
.--.
..-.
..
…
1
1
1
1
1
1
1
1
1
1
3
3
3
1
1
1 3 1 1 (3)
(3)
1 1 (3)
(3)
1 1 [7]
14 единиц
8 единиц
10 единиц
6 единиц
12 единиц
Где () — время между символами, а [] — время между словами. Обратите внимание, что в
конце символа мы вставляем не точку, а время между символами (3 единицы). Аналогично, в
конце слова мы вставляем не точку, а время между словами (7 единиц).
Зная скорость речи (слов в минуту, с./мин), мы можем рассчитать время титра (или бита)
в секундах следующим образом:
Время титра = 60 / (50 × с./мин)
Таким образом, например, при скорости 20 слов в минуту базовое время дита
определяется как: 60 / (50 × 20) = 60 мс.
Программа принимает азбуку Морзе в качестве аудиосигнала и оценивает временную
задержку Dit. Затем автоматически вычисляются остальные временные параметры, код
преобразуется в текст и отображается на ЖК-дисплее.
На рис. 6.167 показана блок-схема проекта. Для приема звукового кода Морзе используется
микрофонный модуль («Mic» ClickBoard). Затем код передается на микросхему декодера тона
(LM567), которая генерирует двоичные значения «высокий» и «низкий» на основе входного
тона. Выход генератора тона подключен к одному из выводов GPIO Raspberry Pi Pico.
Преобразованный код отображается на экране ПК.
Рис. 6.167: Блок-схема проекта.
Микрофон
«Mic Click» — это плата от www.mikroe.com, на которой установлен кремниевый микрофон
поверхностного монтажа SPQ0410HR5H-B с максимальной защитой от радиочастотных помех. Плата
рассчитана на работу от источника питания 3,3 В. SPQ0410HR5H-B, использующий технологию SiSonic™
MEMS, состоит изакустического датчика, малошумящего входного буфера и выходного усилителя.
● 286
Chapter 6 • Amateur Radio Hardware-based Projects
Защита «MaxRF» предотвращает попадание радиочастотных помех, улавливаемых
проводниками, на выход микрофона.
Основные характеристики платы Mic Click:
• Ток потребления: 120 мкА (типичный)
• Чувствительность: –42 дБВ/Па
• Отношение сигнал/шум: 59 дБ(А)
• Общие гармонические искажения: 1%
• Выходное сопротивление: 400 Ом
• Направление: Всенаправленное
Вывод 1 — выходное напряжение. К выводу 7 платы необходимо подключить источник
питания +3,3 В.
Декодер тонального сигнала
На рис. 6.168 показана схема расположения выводов микросхемы тонального декодера
LM567. LM567 — это высокостабильный низкочастотный интегральный декодер с фазовой
автоподстройкой частоты (ФАПЧ). Благодаря хорошей способности подавлять шум и
стабильности центральной частоты, он широко используется в декодировании различного
коммуникационного оборудования и схемах демодуляции для АМ и ЧМ. Микросхема также
используется в таких схемах, как тональный декодер, ультразвуковые регуляторы,
прецизионные генераторы, системы мониторинга и управления частотой, пейджинговые
детекторы и т. д. Тональный декодер LM567 — это устройство, способное определять,
находится ли входной сигнал в пределах выбираемого диапазона обнаружения. Устройство
имеет транзисторный выход с открытым коллектором, поэтому для достижения
соответствующих логических уровней требуется внешний резистор. Когда входной сигнал
находится в полосе обнаружения, выход устройства переходит в низкое состояние.
Внутренняя частота свободного хода генератора управляемого напряжением (ГУН)
определяет центральную частоту полосы обнаружения. Для регулировки этой частоты
требуется внешний RC-фильтр. Полоса пропускания, в пределах которой устройство будет
обнаруживать желаемую частоту, зависит от емкости на выводе петлевого фильтра. Обычно
к этому выводу подключается конденсатор емкостью 1 мкФ.
Описание выводов LM567 приведено в таблице 6.5.
Рис. 6.168: Распиновка LM567.
● 287
Raspberry Pi Pico for Radio Amateurs
Таб. 6.5: Распиновка LM567
LM567 обладает следующими основными характеристиками:
•
•
•
•
•
•
•
•
Рабочее напряжение: от 4,5 В до 9,0 В
Ток потребления в активном режиме: 12 мА (типичный)
Ток потребления в режиме ожидания: 7 мА (типичный)
Наименьшее обнаруживаемое входное напряжение: 20 мВrms
Максимальная центральная частота: 500 кГц
Стабильность центральной частоты: 35 ± 60 ppm/°C
Напряжение насыщения на выходе: 0,2 В (типичное)
Скорость переключения: центральная частота / 20
Схема подключения
На рис. 6.169 показана принципиальная схема проекта. Выводы 4 и 7 подключены к +5 В и
GND Raspberry Pi Pico. Аудиовход азбуки Морзе подается на вывод 3 через конденсатор 470
нФ. Выход имеет открытый коллектор и снимается с вывода 7.
Центральная частота декодера тона LM567 равна частоте холостого хода управляемого
напряжением генератора. Для установки этой частоты необходимо добавить внешние
компоненты. Значения компонентов указаны ниже:
Где R1 = резистор синхронизации на выводе 5, C1 = конденсатор синхронизации на выводе 6.
Используя резистор 10 кОм, включенный последовательно с потенциометром 10 кОм и
конденсатором 0,1 мкФ, центральная частота может принимать следующие значения при
изменении положения потенциометра:
10 кОМ
5
1
0
● 288
кОм
kОм
кОм
Chapter 6 • Amateur Radio Hardware-based Projects
Тогда диапазон частот f0 = 500–800 Гц должен быть приемлемым выбором при положении
ползунка потенциометра между полным и половинным ходом.
Для устранения нежелательных сигналов, которые могут запускать выходной каскад, в
LM567C предусмотрен фильтр постдетектирования. Этот фильтр состоит из внутреннего
резистора 4,7 кОм и внешнего конденсатора. Хотя обычно значение внешнего конденсатора
не критично, рекомендуется использовать значение как минимум вдвое большее, чем
значение конденсатора контурного фильтра. Если значение конденсатора выходного фильтра
слишком велико, время включения и выключения выхода будет иметь задержку до тех пор,
пока напряжение на этом конденсаторе не достигнет порогового уровня.
Полоса пропускания зависит от конденсатора, подключенного к выводу 2 (C2), и выражается
в процентах от центральной частоты, где (при условии Vi <= 200 мВ среднеквадратичного
значения):
Где Vi — среднеквадратичное напряжение, f0 — частота, а C2 — мкФ.
Например, при f0 = 600 Гц и C2 = 1 мкФ полоса пропускания составит около 20% от центральной
частоты, которая приблизительно равна 120 Гц. Меньшее значение C2 увеличит полосу
пропускания, а большее — уменьшит.
Выходной фильтр определяется конденсатором C3. Хотя рекомендуется выбирать значение,
как минимум вдвое превышающее значение C2, установлено, что значение около 1 мкФ дает
удовлетворительные результаты.
Скорость переключения LM567 зависит от центральной частоты. При f0 = 550 Гц скорость
переключения составляет 550 / 20 = 27,5, а при f0 = 800 Гц — 800 / 20 = 40. Поэтому для более
высокой скорости переключения необходимо выбирать более высокие центральные частоты.
Поскольку выход LM567 имеет открытый коллектор, необходимо подключить к этому выводу
подтягивающий резистор, как показано на рис. 6.169. Светодиод подключен последовательно
с подтягивающим резистором, что обеспечивает визуальную индикацию принимаемого кода
Морзе, выводимого тональным декодером.
На рис. 6.170 показано определение частоты, где выходное состояние меняется
(переходит из высокого уровня в низкий), когда входной сигнал достигает центральной
частоты.
● 289
Raspberry Pi Pico for Radio Amateurs
Рис. 6.169: Схема проекта.
Рис. 6.170: Обнаружение частоты.
Листинг программы показан на рис. 6.171 (программа:MorseDecoder.py). В этой программе
азбука Морзе встраивается в двоичную версию чисел от 2 до 63, как описано Баддом
Чёрчвордом (WB7FHC, VK2IDL_Morse_Decoder_2.7, ссылка:
https://github.com/ideal54/VK2IDL_CW_Decoder).
Операция выполняется следующим образом. Изначально в переменной, скажем, MyNum, хранится
значение 1. После получения dit или dah это число сдвигается влево. Если получен dit, MyNum
увеличивается на единицу; если получен dah, к числу добавляется 0, и обрабатывается следующий
dit или dah. Для преобразования числа в MyNum в буквы и цифры используется следующая строка:
Morse = "##TEMNAIOGKDWRUS##QZYCXBJP#L+F
VH09#8###7#####/-61#######2###3#45";
dah - тире
dit - точка
● 290
Chapter 6 • Amateur Radio Hardware-based Projects
В качестве примера ниже приведены некоторые символы и число, хранящееся в MyNumba
(помните, что к числу всегда добавляется 1 слева):
Morse code:
dah
Letter: T
MyNum (binary):
10
MyNum (decimal):
2
dit
E
11
3
dahdah
M
100
4
dahdit
N
101
5
ditdah
A
110
6
ditdit
I
111
7
Если теперь использовать MyNumas в качестве индекса в строке Morse, мы получим
соответствующие символы, например, Morse[2] = T, Morse[3] = E, Morse[4] = M и так далее.
Обратите внимание, что позиции индексов символов # не используются, т.е. Morse[0] и Morse
[1] не используются.
В начале программы импортируются используемые библиотеки. Текст MORSE отображается
в верхней строке ЖК-дисплея в течение 2 секунд. Программа состоит из 2 функций: Setup() и
Decode().
Setup(): Эта функция принимает азбуку Морзе, состоящую как минимум из 10 точек и тире, а
затем находит максимальное время появления точки в миллисекундах и сохраняет его в
переменной ditmax. Поэтому необходимо предварительно обучить программу, отправив
несколько символов (например, ABC-DEF). Это значение используется в функции Decode()
для определения того, получена ли точка или тире. Фрагменты входного сигнала
определяются с помощью операторов while. Например, следующие операторы ожидают, пока
сигнал не изменится с 1 на 0. Встроенная функция utime.ticks_ms() используется для
определения длительности в миллисекундах высоких или низких значений входного сигнала.
while signal.value() == 1:
pass
Decode(): Это основная функция программы, в которой принимается азбука Морзе и
преобразуется в буквы и цифры. Переменная MyNumis изначально установлена в 1. После
получения низкого и высокого сигналов переменная MyNumis сдвигается влево на одну
позицию, так что она содержит двоичное число 10. Затем программа определяет, был ли
низкий сигнал «дита» или «дах». Переменные Mark и Space обозначают состояния низкого и
высокого сигнала соответственно, где низкий уровень соответствует полученному тону, а
высокий — отсутствию тона. Ниже приведён код, выполняющий эту операцию,
преобразующий код в букву или цифру и отображающий её на ЖК-дисплее:
#--------------------------------------------------------------#
ДЕКОДЕР КОДА МОРЗЕ
#
-------------------
#
# Это проект декодера азбуки Морзе, реализованный на Raspberry Pi Pico.
# Для приема звукового сигнала азбуки Морзе используется плата Mic Click,
# оснащенная микрофоном. Затем этот сигнал подается на микросхему
# тонального декодера LM567. Частота срабатывания тонального декодера
# устанавливается с помощью потенциометра. К выходу тонального
# декодера подключен светодиод, что упрощает регулировку частоты.
● 291
Raspberry Pi Pico for Radio Amateurs
# Рекомендуется использовать аудиочастоту около 800 Гц. Raspberry Pi Pico
# декодирует азбуку Морзе и отображает её в текстовом виде на ЖК-дисплее
#
# Author: Dogan Ibrahim
# File
: MorseDecoder.py
# Date
: Oct 2021
#--------------------------------------------------------------from machine import Pin, I2C
import utime
from pico_i2c_lcd import I2cLcd
i2c_lcd = I2C(id=1,scl=Pin(3),sda=Pin(2),freq=100000)
lcd = I2cLcd(i2c_lcd, 0x27, 2, 16)
Morse = “##TEMNAIOGKDWRUS##QZYCXBJP#L+FVH09#8###7#####/-61#######2###3#45”
lcd.clear()
lcd.putstr(“MORSE”)
utime.sleep(2)
lcd.clear()
global ditmax, MyNum
maxdit = [0]*10
MyNum = 1
#
# Сигнальные соединения. Аноним Морзе подается на GP0 через декодер тона
#
signal = Pin(0, Pin.IN)
# На пине GP0
#
# Найти максимальное время точки и тире, прослушивая некоторый код. ditmax — это
# максимальное измеренное время точки, которое используется позже в коде
#
#
def Setup():
global ditmax, dahmax
for i in range(0, 10):
while signal.value() == 1:
# Ждать 1 сек
pass
utime.sleep(0.01)
TmrStrt = utime.ticks_ms()
# Прошедшее время
while signal.value() == 0:
# Ждать 0 сек
pass
utime.sleep(0.01)
TmrEnd = utime.ticks_ms() - 20
● 292
# Прошедшее время
Chapter 6 • Amateur Radio Hardware-based Projects
maxdit[i] = utime.ticks_diff(TmrEnd, TmrStrt)
dahmax = max(maxdit)
ditmax = dahmax / 3
#
# Эта функция работает непрерывно, декодируя и отображая
# азбуку Морзе на ЖК-дисплее
#
def Decode():
global MyNum, ditmax
colcnt = 0
flag = 0
while signal.value() == 1:
pass
utime.sleep(0.01)
while True:
TmrStrt = utime.ticks_ms()
while signal.value() == 0:
pass
utime.sleep(0.01)
TmrEnd = utime.ticks_ms()
MarkTime = utime.ticks_diff(TmrEnd, TmrStrt)
TmrStrt = utime.ticks_ms()
while signal.value() == 1:
if (utime.ticks_ms() - TmrStrt) > 5 * ditmax:
flag = 1
break
utime.sleep(0.01)
TmrEnd = utime.ticks_ms()
SpaceTime = utime.ticks_diff(TmrEnd, TmrStrt)
MyNum = MyNum << 1
if MarkTime < 2*ditmax:
MyNum = MyNum + 1
if SpaceTime > 2*ditmax:
colcnt = colcnt + 1
if colcnt > 32:
# ЖК-дисплей заполнен?
lcd.clear()
# Очистить ЖК-дисплей
colcnt = 0
# Начать новую строку
# Подождите, пока очистится
# Отобразить текст
utime.sleep(0.005)
lcd.putstr(Morse[MyNum])
MyNum = 1
if flag == 1:
break
● 293
Raspberry Pi Pico for Radio Amateurs
Setup()
while True:
Decode()
Рис. 6.171: Программа: MorseDecoder.
Тестирование программы
Шаги для тестирования программы:
• Сборка оборудования.
• Подайте питание на Raspberry Pi Pico. Убедитесь, что зеленый светодиод на плате Mic Click
включен. Запустите программу (нажмите зеленую кнопку, если используете Thonny). Убедитесь,
что текст MORSE отображается на ЖК-дисплее в течение 2 секунд. Если этого не происходит,
проверьте оборудование, прежде чем продолжить.
• Используйте программу генерации аудиосигнала азбуки Морзе на своем мобильном
телефоне. Например, программа «Morse Code Translator», доступная в Интернете (ссылка:
https://morsecode.world/international/translator.html
Рис. 6.172: Программа-переводчик азбуки Морзе.
Нажмите «Настроить» и установите скорость 12 слов в минуту, тон 800
Гц и максимальную громкость 100, как показано на рисунке 6.173.
● 294
Chapter 6 • Amateur Radio Hardware-based Projects
Рис. 6.173: Настройка программы.
Поднесите смартфон близко к микрофону платы Mic Click, введите несколько букв в
окне с надписью «Перевести сообщение», например, ABCDEFG (см. рис. 6.174), и
нажмите «Воспроизвести». Медленно поворачивайте потенциометр частоты, пока
светодиод не начнет мигать. Светодиод будет мигать по мере того, как азбука Морзе
будет выводиться через динамик смартфона. Через некоторое время азбука Морзе
будет преобразована в буквы и отображена на ЖК-дисплее. Обратите внимание, что
первые несколько букв отображаться не будут, так как они будут использоваться для
установки скорости в программе. С этого момента все буквы будут отображаться
правильно.
Рис. 6.174: Введите несколько букв для тестирования.
● 295
Raspberry Pi Pico for Radio Amateurs
Программа была протестирована на скорости до 80 слов в минуту. Было установлено, что
до скорости около 60 слов в минуту символы принимаются, преобразуются и отображаются
корректно. При скорости выше 60 слов в минуту большинство символов отображаются
правильно, но иногда возникают ошибки.
Рекомендуется поддерживать высокий уровень громкости и располагать аудиовыход
близко к микрофону Mic clickboard.
На рис. 6.175 показан проект, собранный на макетной плате. Возможно, вам
захочется сохранить файл programasmain.py (см. главу 7), чтобы он запускался
автоматически после перезагрузки.
Рис. 6.175: Проект, собранный на макетной плате.
6.23 Raspberry Pi PicoRTL-SDR
В 2012 году была обнаружена ранее не задокументированная функция микросхемы
RTL2832U, которая позволила использовать её в качестве универсального
программно-определяемого радио (SDR). С развитием аппаратного и программного
обеспечения эти недорогие «донглы» теперь можно использовать в качестве сложных
SDR-приёмников. Например, RTL-SDR-донгл можно подключить к Raspberry Pi, и на Raspberry
Pi можно загрузить множество интересных программных пакетов.
Без этих донглов подобные приёмники с аналогичными функциями стоили бы сотни
или тысячи долларов. Некоторые области применения RTL-SDR-донглов:
• Прослушивание разговоров диспетчеров воздушного движения
•
•
•
•
•
•
● 296
Отслеживание местоположения самолетов
Прием метеорологических сигналов
Прослушивание любительских радиодиапазонов
Прослушивание коротковолнового и FM-радио
Прослушивание DAB-трансляций
Прием и декодирование сигналов GPS
Chapter 6 • Amateur Radio Hardware-based Projects
•
•
•
•
•
•
•
Декодирование APRS-пакетов любительской радиосвязи
Разработка радиосканера
Просмотр аналогового телевещания
Использование в качестве анализатора спектра
Использование в качестве приемопередатчика
Прослушивание спутников
Сканирование беспроводных телефонов и радионянь
Минимальные требования для использования RTL-SDR-донгла:
• Устройство RTL-SDR (донгл)
• Подходящая антенна (некоторые поставляются с антеннами)
• Мощный компьютер (например, Raspberry Pi 4)
• Драйвер и программное обеспечение RTL-SDR (их много,
и большинство из них бесплатны)
В зависимости от ваших требований и приложений, вам также может потребоваться
использовать фильтры для улучшения отношения сигнал/шум.
Устройства RTL-SDR могут работать в диапазоне частот от 24 МГц до более 1,7 ГГц. Более
низкий частотный диапазон может быть расширен за счет использования повышающего
преобразователя или режима прямой выборки. Повышающий преобразователь подключается
к антенне перед устройством RTL-SDR. Некоторые повышающие преобразователи работают
на частотах всего в несколько кГц. Если частота генератора повышающего преобразователя
составляет 125 МГц, а нам нужно настроиться на 5 МГц, то нам нужно настроить приемник на
130 МГц. Режим прямой выборки требует внесения небольших изменений в аппаратное и
программное обеспечение RTL-SDR, где соединение выполняется внутри аппаратной части.
Некоторые устройства RTL-SDR имеют небольшое отверстие для соединения путем вставки
перемычки, поэтому нет необходимости открывать устройство и выполнять пайку.
Программное обеспечение должно быть настроено таким образом, чтобы режим выборки был
установлен на «Прямая выборка».
RTL-SDR имеет полосу пропускания 3,2 МГц, 8-битный аналого-цифровой преобразователь
(АЦП), коэффициент шума менее 4,5 дБ и входное сопротивление 75 Ом (т.е. не 50 Ом, как в
любительской радиосвязи. В целом, рассогласование между 75 Ом и 50 Ом составляет
менее 0,2 дБ). Поскольку устройства RTL-SDR недороги, они используют кварцевые
генераторы с частотой 28,8 МГц, и точность их тактовой частоты может изменяться на
несколько кГц. В большинстве популярных программных пакетов для RTL-SDR есть опции в
виде значений дрейфа в ppm для калибровки этого дрейфа в программном обеспечении.
Также присутствуют пиковые шумы в виде гармоник на частотах, кратных 28,8 МГц. Эти пики
обычно можно наблюдать на водопадных диаграммах.
Для обеспечения хорошего приема и низкого уровня шума RTL-SDR следует размещать
близко к антенне, чтобы фактически заменить коаксиальный кабель с потерями на
USB-кабель без потерь. Однако следует убедиться, что длина USB-кабеля не превышает 5
метров для USB 2.0 или 3 метров для USB 3.0. Если требуются более длинные
USB-кабели, рекомендуется использовать USB-концентраторы или USB-ретрансляторы.
● 297
Raspberry Pi Pico for Radio Amateurs
RTL-SDR-донглы следует размещать в металлических корпусах, чтобы минимизировать
внешние помехи, и они не должны находиться рядом с линиями электропередач,
двигателями, телевизорами, электроприборами или другим оборудованием, которое может
создавать электромагнитные помехи.
Наличие хорошей антенны также особенно важно при использовании RTL-SDR. Дешевая
антенна, обычно поставляемая с устройством, имеет длину около 12-15 см и, как правило, не
подходит для любительской радиосвязи. Для создания четвертьволновой антенны и
улучшения характеристик приема следует разместить эту антенну над металлической
поверхностью радиусом около 12-15 см.
Устройства RTL-SDR отлично работают на мощных компьютерах типа Raspberry Pi 4,
обладающих быстрым процессором, значительным объемом памяти и необходимыми для
работы с RTL-SDR устройствами USB-портами.
К сожалению, из-за ограничений аппаратного и программного обеспечения Raspberry Pi Pico
установить на него аппаратное и программное обеспечение RTL-SDR невозможно. На момент
написания этой книги радиолюбитель Луиджи Круз сообщил (ссылка:
https://www.rtl-sdr.com/piccolosdr-a-simple-sdr-from-a-raspberry-pi-pico/
АЦП на Pico можно использовать как простой SDR с прямой выборкой и полосой пропускания
всего 250 кГц. Это, конечно, ограничено, и прием сигнала возможен только в низкочастотном
диапазоне, а сигналов там не так много. Хотя это интересный проект, демонстрирующий эту
идею, на практике он не особенно полезен.
6.24 Проект 37: Использование пары передатчик/приемник
FS1000A 433 МГц
Передатчик FS1000A и совместимый с ним приемник (XY-MK-5V) — это очень
недорогие модули передатчика/приемника, стоимость которых составляет всего
несколько долларов (см. рис. 6.176). Это модули передатчика/приемника ближнего
действия, которые можно использовать, например, на любительской радиостанции
для управления реле и т. д.
Основные характеристики модуля передатчика:
•
•
•
•
Частота передачи: 433,92 МГц, 315 МГц, 330 МГц
Рабочее напряжение: от 3 В до 12 В
Мощность передачи: от 10 мВт до 40 мВт; 16 дБм
Дальность передачи: от 20 до 100 метров через стены и
максимум 500 метров на открытой местности
• Скорость передачи данных: <10 Кбайт в секунду (дальность
снижается при скорости выше 2400 байт в секунду)
• Тип модуляции: OOK
• Потребляемый ток: от 20 до 28 мА
• Потребляемый ток в режиме ожидания: 0 мА
● 298
Chapter 6 • Amateur Radio Hardware-based Projects
Основные характеристики приемного модуля:
•
•
•
•
•
Приемная частота: 433,92 МГц, 315 МГц, 330 МГц
Рабочее напряжение: 5 В
Чувствительность приемника: –105 дБ
Тип модуляции: OOK
Потребление тока в режиме ожидания: 4 мА
Рис. 6.176: FS1000A и соответствующий приемник.
Модули передатчика/приемника работают только в одном направлении, то есть модуль
передатчика может только передавать, а модуль приемника — только принимать.
В этом проекте модуль передатчика подключен к Raspberry Pi Pico, а модуль приемника — к
Arduino UNO. Кроме того, к Pico подключена кнопка, а к Arduino — реле. Нажатие кнопки на
Pico отправляет команду на Arduino по беспроводной связи через модули
передатчика/приемника для активации реле. Отпускание кнопки деактивирует реле.
На рис. 6.177 показана блок-схема проекта.
● 299
Raspberry Pi Pico for Radio Amateurs
Рис. 6.177: Блок-схема проекта.
Схема проекта показана на рис. 6.178. Вывод данных передатчика подключен к выводу GP0
платы Raspberry Pi Pico и питается от +3,3 В. Состояние кнопки обычно высокое, и она
подключена к выводу GP13 платы Pico. Нажатие кнопки изменяет её состояние на низкое. Вывод
данных приёмника подключен к выводу 2 платы Arduino, которая настроена как
программно-управляемый UART-приёмник. Реле подключено к выводу 4 платы Arduino.
Рис. 6.178: Схема проекта.
В проекте представлены две программы: программа для Raspberry Pi Pico и программа для
Arduino UNO. Подробности приведены ниже.
Программа для Raspberry Pi Pico: На рис. 6.179 показана программа для Raspberry Pi Pico
(pro-gram:TX433.py). Данные передаются на модуль передатчика через последовательный
UART на Raspberry Pi Pico. UART инициализирован на скорость 1200 бод (бит/с). Кнопка
назначена на вывод GP13 и сконфигурирована как вход с подтягивающим резистором.
Остальная часть программы выполняется в цикле «while». Внутри этого цикла
проверяетсясостояние кнопки. Если кнопка нажата, то через передатчик отправляется
буква I (обозначающая IN) для активации реле.
● 300
Chapter 6 • Amateur Radio Hardware-based Projects
Если же кнопка отпущена, то через передатчик отправляется буква O (для OUT) для
деактивации реле.
#--------------------------------------------------------------#
ИСПОЛЬЗОВАНИЕ ПЕРЕДАТЧИКА-ПРИЕМНИКА FS1000A 433 МГц
#
========================================================
#
# В этом проекте используются передатчик FS100A и
# совместимые с ним приемные модули. Передатчик подключен к
# Raspberry Pi, а приемник — к Arduino UNO. Кроме того, к Pico
подключена кнопка, а к Arduino — реле. Нажатие на кнопку
# отправляет команду Arduino по паре TX-RX 433 МГц для
# активации реле. Реле деактивируется при отпускании кнопки.
# Кнопка подтягивается к высокому уровню внутри
# микроконтроллера Pico
#
# Author: Dogan Ibrahim
# File
: TX433.py
# Date
: Sept 2021
#---------------------------------------------------------------from machine import Pin, UART
import utime
Button = Pin(13, Pin.IN, Pin.PULL_UP)
# Кнопка на пине 13
uart = UART(0, 1200)
# UART
while True:
if Button.value() == 1:
uart.write("O")
elif Button.value() == 0:
uart.write("I")
utime.sleep(0.02)
# Если кнопка не нажата
# Реле выключено
# Если кнопка нажата
# Реле включено
Рис. 6.179: Программа: TX433.py .
Программа для Arduino UNO: На рис. 6.180 показана программа для Arduino UNO (программа:
RX-433.c). В начале программы в программу включается библиотека программного
обеспечения для последовательного порта, а контакты 2 и 3 настраиваются как контакты RX и
TX соответственно (TX I здесь не используется). Затем реле назначается на контакт порта 4 и
деактивируется в начале программы. Внутри цикла программы команды принимаются с
последовательного порта через модуль приемника. Если команда I, то реле активируется.
Аналогично, если команда O, то реле деактивируется.
● 301
Raspberry Pi Pico for Radio Amateurs
/***********************************************************
*
ПРОЕКТ ПЕРЕДАТЧИКА-ПРИЕМНИКА FS1000A 433 МГц
*
================================================
*
* В этом проекте используются передатчик FS1000A и совместимые
* модули приемника. Передатчик подключен
* к Raspberry Pi Pico, а приемник — к
* Arduino UNO. Кроме того, к
* Pico подключена кнопка, а к Arduino — реле. Нажатие
* кнопки активирует реле.
*
* Author: Dogan Ibrahim
* Date
: Sept 2021
* File
: RX133.c
***********************************************************/
#include <SoftwareSerial.h>
// Библиотека последовательного порта
SoftwareSerial MySerial(2, 3);
// RX, TX
char cmd;
#define Relay 4
// Реле на контакте 4
int on, off;
void setup()
{
MySerial.begin(1200);
// Скорость программного порта 9600
pinMode(Relay, OUTPUT);
// Реле — выход
digitalWrite(Relay, LOW);
// Реле выключено
}
void loop()
{
if(MySerial.available() > 0)
// Данные доступны?
{
cmd = MySerial.read();
// Чтение данных
if(cmd == 'I')
// I ?
digitalWrite(Relay, HIGH);
else if(cmd == 'O')
// Активация реле
// O ?
digitalWrite(Relay, LOW);
// Деактивация реле
}
}
.
Рис. 6.180: Программа: RX433.c.
● 302
Chapter 6 • Amateur Radio Hardware-based Projects
На рис. 6.181 показан проект, собранный на макетной плате. Обратите внимание, что автор не
использовал антенну в ходе тестирования. Без антенны дальность действия модулей
составляет около 3 метров. С вертикальной четвертьволновой антенной диаметром 173 мм
дальность увеличивается примерно до 100 метров. Заинтересованные читатели могут найти
профессиональные модули TX-RX сверхдальнего действия на следующем сайте:
www.radiometrix.co.uk
Рис. 6.181: Проект, собранный на макетной плате.
● 303
Raspberry Pi Pico for Radio Amateurs
Глава 7 • Автоматический запуск программы после загрузки
Raspberry Pi Pico
В некоторых приложениях может потребоваться автоматический запуск программы после
загрузки Raspberry Pi Pico. Проще всего это сделать на простом примере.
На рис. 7.1 показана простая программа, которая мигает светодиодом, подключенным к контакту
порта GP6, каждую секунду. Мы настроим Raspberry Pi Pico так, чтобы светодиод начинал мигать
сразу после загрузки Pico.
#---------------------------------------------------------#
АВТОМАТИЧЕСКИЙ ЗАПУСК ПРОГРАММЫ ПОСЛЕ ПЕРЕЗАГРУЗКИ
#
========================================================\
#
# В некоторых приложениях может потребоваться автоматический
# запуск программы после перезагрузки. Это легко сделать,
# сохранив программу под именем "main.py".
# Эта очень простая программа автоматически мигает светодиодом,
# подключенным к GP16, после загрузки Raspberry Pi Pico.
#
# Author: Dogan Ibrahim
# File
: main.py
# Date
: February 2021
#-----------------------------------------------------------from machine import Pin
import utime
LED = Pin(16, Pin.OUT)
# Светодиод на пине 16
while True: # Делать вечно
LED.value(1)
# Светодиод включен
utime.sleep(1)
# Подождите 1 секунду
LED.value(0)
# Светодиод выключен
utime.sleep(1)
# Подождите 1 секунду
Рис. 7.1: Простая программа, управляющая миганием светодиода.
Последовательность действий следующая:
• Присвойте программе имя и запустите её, чтобы убедиться в отсутствии ошибок
и корректной работе (в данном случае светодиод мигает каждую секунду).
• Остановите программу, выбрав пункт меню «Run» в меню Thonny,
а затем «Stop/Restart backend».
• Нажмите «File», затем «Save as» и нажмите «Raspberry Pi Pico» (рис. 7.2),
чтобы сохранить файл в памяти Raspberry Pi Pico.
● 304
Chapter 7 • Running a Program Automatically after the Raspberry Pi Pico Boots
Рис. 7.2: Нажмите «Raspberry Pi Pico», чтобы сохранить файл.
• Введите имя файла main.py и нажмите OK.
• Убедитесь, что файл сохранен правильно. Нажмите « file», затем «Open» и
нажмите «Raspberry Pi Pico». Вы должны увидеть файл с именем main.py
(Рис. 7.3). Возможно, вам придется прокрутить список вниз.
Рис. 7.3: Файл main.py.
• Перезагрузите Raspberry Pi Pico, и вы увидите, как светодиод начнет
мигать сразу после загрузки Pico.
• Вы можете остановить программу из Python, нажав «RUN»,
а затем «Stop/Restart. backend».
• Если вы не хотите, чтобы программа запускалась автоматически,
вам следует удалить или переименовать файл main.py.
● 305
Raspberry Pi Pico for Radio Amateurs
APPENDIX
Parts Used in Projects
1
4
8
2
8
1
1
1
1
1
1
2
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
Rotary encoder
Pushbutton switch
LED
10 kΩ resistor
470 Ω resistor
220 Ω resistor
2.2 kΩ resistor
1 kΩ resistor
3.3 kΩ resistor
4.7 kΩ resistor
470 nF capacitor
1 µF capacitor
100 nF
250 µF capacitor
10 kΩ potentiometer
Buzzer
Transistor, small-signal, NPN, e.g. BC108
4-way relay (Elegoo)
DHT11
4×4 Keypad
GPS Click + Antenna (mikroelektronika)
HC-06 Bluetooth
RF Meter Click (mikroelektronika)
AudioAmp Click (mikroelektronika)
Mic Click (mikroelektronika)
LM567 tone decoder
TEA5767 FM radio chip
RC522 RFID controller + tags
Parallel LCD
I2C LCD
SN74LV8154
MCP4921 DAC
AD9850 DDS
RadioStation Click (mikroelektronika)
ESP01
DS1307 RTC
FS1000A 433 MHz TX-RX modules
Raspberry Pi Pico with pinheaders (Elektor)
microUSB cable
● 306
Index
Index
$GPGLL
4×4 keypad
139
172
A
accurate timing
AC parameters
Active buzzers
active-LOW
active low-pass filters
AD8318
AD9850 signal generator
ADC
air core coil
Amateur Radio exams
Ammeter
ampère meter
analog input
Arbitrary periodic waveform
Astable circuit
atitude and longitude
attack rate
audio amplifier
Auto boot
Automatic Gain Control
Average
148
80
218
125
84
196
164
187
74
217
187
190
188
156
90
137
208
256
250
237
38
B
bandwidth
Battery operation
Binary
Binary counting
binary divider
Bipolar junction transistor
bistable
BJT
Bluetooth
Bluetooth Controller
BOOTSEL
brightness control
bus expander chip
Butterworth filter
72
250
49
109
186
77
90
77
260
263
12, 27, 34
115
121
92
C
Calculator
Capacitance meter
capacitive humidity sensor
carrier signal
cathode terminal
Cauer topology
C/C++
channel separation
Character spacing
common-emitter transistor amplifier
conversion time
cosine
current date and time
current-sinking mode
current-sourcing mode
cut-off frequency
187
135
207
67
93
27
237
217
80
187
43
129
103
102
85
D
DAC
144
Dah
217
damping factor
88
dB
204
dBm
204
DGPS
137
DHT11
134
dht11.py
135
Dice
46
digital audio limiter
208
Digital-to-Analog Converter
144
direct-sampling mode
297
Dit
217
DSP
207
duty cycle
91, 171, 257, 259
dynamic range
208
E
Enable
end = ' '
ESP-01
European RDS
external LED
external timer
114
39
278
208
101
182
F
45
File processing
47
● 307
Raspberry Pi Pico for Radio Amateurs
filter frequency response
Fixed-frequency
flat frequency response
FM modulation
FM radio
forward voltage
Frequency counter
frequency-entry
frequency modulation
frequency oscillator
frequency response
FS1000A
85
164
209
207
236, 244
66
181
171
207
237
69
298
G
geographical coordinates
GPS
GPS Click board
ground plane
137
137
138
89
H
harmonic distortion
harmonic filtering
HC-06
HD44780
hexadecimal
237
208
260
113
49
I
I2C addresses
I2C device address
I2C LCDs
IF selectivity
Impedance matching
INDEX.HTM
inductance
INFO_UF2.TXT
Installing MicroPython
inter-character time
intermediate frequency
internal pull-up resistors
internal timer
inter-word time
143
143
121
237
96
28
74
28
27
217
207
107
182
217
K
keypad
KY-051
● 308
171
123
L
lcd_clear
lcd_cursor_blink
lcd_cursor_off
lcd_cursor_on
LCD functions
lcd_goto(col,row)
lcd_home
lcd_init
lcd_putch(c)
lcd_puts(s)
LEA-6S
Least Significant Bit
LM386
LM555/NE555
LM567
logarithmic-law
logarithmic scale
logic level converter
LSB resolution
L-type matching
116
116
116
116
115
117
116
116
116
116
138
237
244
90
287
199
204
14
145
96
M
magnitude and phase
math library
matrices
maximum power transfer
MCP3201
MCP4921
Measuring the period
MFRC522
Mic Clic
MicroPython
Monostable
Monostable circuit
Morse Code
Morse Code exerciser
Morse speed
Most Significant Bit
69
39
50
96
196
144
181
265
286
27
90
90
217
217
225
237
N
NMEA sentence
normally-closed
NPN transistor
137
125
219
Index
O
octal
Ohmmeter
on-board LED
On/Off power control
overshoot
49
187
99
125
84
P
parallel LCDs
PARIS
Passive buzzers
passive filters
Passive filters
PCF8574N
PCSGU250
peak-to-peak amplitude
phase-locked loop
Phase-locked loop
phase modulation
Pin.IRQ_FALLING
Pin.IRQ_HIGH_LEVEL
Pin.IRQ_LOW_LEVEL
Pin.IRQ_RISING
Pi-type attenuator
PLL
PLL reference frequency
PLL register
potential divider
Power gain
Power-on reset
pre-emphasis
pre-emphasis filter
programmable gain
pull-up resistors
pushbutton interrupts
112
217
218
69
92
121
148
161, 170
287
237
164
105
105
105
105
61
287
238
238
14, 57
204
237
209
209
208
122
104
Q
Q factor
QFN-56 package
quarter-wave
72, 84, 88
12
89
R
radio broadcast band
RadioStation Click
randint
random characters
206
206
46
222
RC522
RC circuits
RDS deviation
RDS / RBDS
RDS/RDBS
Read/Write
real-time clock
REFCLOCK
Register Select
Relay sequencer
release rate
resistive attenuator
Resistive attenuator
Resonance
RF attenuators
RFID
RFID card reader
RF power attenuator
RF power meter
RLC circuit
rotary encoder
RPI-RP2
RTL2832U
RTL-SDR
RX
RXD
265
69
209
216
206
114
129
166
114
232
208
61
59
71
203
265
267
196
196
71
225
30
296
296
140
261
S
Sallen-Key
sample and hold
sawtooth signal
SCL
SDA
second-order low-pass active filter
Sensitivity
serial link
serial mode
series-resonance
Series-Shunt
Shell
Shunt-Series
Si4713-B30
signal-to-noise ratio
Signal to noise ratio
sinewave signal
Single-layer coils
84
201
152
121
121
84
287
140
165
71
96
32
96
206
209
287
158
74
● 309
Raspberry Pi Pico for Radio Amateurs
SMPS
SN74LV8154
Software Defined Radio
Software mute
Sort
Sorting
SPI bus interface.
Squares
squarewave signal
Standby mode
State Machines
Station clock
Station security
Step-time response
sum
switching speed
15, 16
182
296
237
47
47
144
41
145
237
270
129
265
89
39
289
T
tangent
TCP/IP
TEA5767
temperature and humidity
thermistor
Thonny Python IDE
Thonny text editor
time constant
timer interrupt
timer interrupts
tone decoder
touchtone decoding
triangular-wave signal
trigger pulse
trigonometric sine
T-type attenuator
TX
TXD
300
276
268
297
208
V
VBUS
● 310
13, 16
89
204
205
65
187
13, 16, 187
W
Waveform generators
Wi-Fi network
Word spacing
words per minute
144
272
217
218
X
XY-MK-5V
298
Z
Zener diode
43
272
236
134
135
31
99
193
148
161
287
287
154
90
42
60
140
261
U
UART
UDP Server
UID number
upconverter
US RBDS
vertical antenna
voltage gain
voltage generator
voltage regulator
Voltmeter
VSYS
65
books
books
Raspberry Pi Pico для
радиолюбителей
Программирование и разработка радиотехнических
средств, инструментов и приборов для любительской
радиосвязи на базе Raspberry Pi.
Хотя большая часть классического КВ-оборудования и
мобильной техники по-прежнему используется значительным
числом радиолюбителей, использование компьютеров и
цифровых технологий стало очень популярным среди
радиолюбителей. Сегодня любой может приобрести компьютер
Raspberry Pi Pico за 4 евро и разработать множество проектов
для радиолюбителей, используя «Pico» и некоторые внешние
компоненты. Эта книга предназначена для радиолюбителей,
студентов-электронщиков и всех, кто заинтересован в изучении
использования Raspberry Pi Pico для создания своих
электронных проектов. Книга подходит как для начинающих в
электронике, так и для тех, кто имеет большой опыт.
В книге пошагово описана установка среды
программирования MicroPython. Некоторые знания языка
программирования Python помогут понять и
модифицировать проекты, представленные в книге. Книга
знакомит с Raspberry Pi Pico и приводит примеры множества
универсальных программных проектов, которые знакомят
читателя с языком программирования Python. Помимо
программных проектов, разработанных специально для
радиолюбителей, в главе 6 представлено более 36
аппаратных проектов для радиолюбителей, в том числе:
>
>
>
>
>
>
>
>
Station mains power on/off
control
Radio station clock
GPS based station geographical
coordinates
Radio station temperature and
humidity
Various waveform generation
methods using software and
hardware (DDS)
Frequency counter
Voltmeter / ammeter /
ohmmeter / capacitance meter
RF meter and RF attenuators
>
>
>
>
>
>
>
>
Morse code exercisers
RadioStation Click board
Raspberry Pi Pico based
FM radio
Using Bluetooth and Wi-Fi
with Raspberry Pi Pico
Radio station security with RFID
Audio amplifier module with
rotary encoder volume control
Morse decoder
Using the FS1000A TX-RX
modules to communicate
with Arduino
Все программы, обсуждаемые в данной публикации, доступны
на веб-странице ресурсов и информации книги по адресу
www.elektor.com/books.
Профессор Доган Ибрагим
имеет степень бакалавра с
отличием в области
электронной инженерии,
степень магистра в области
автоматического управления и
степень доктора философии в
области цифровой обработки
сигналов. Доган работал во
многих промышленных
организациях, прежде чем
вернуться к академической
деятельности. Он много лет
работал со многими
микропроцессорами и
микроконтроллерами, включая
Z80, 6800, 6809, 8748, 8751,
8080, 8085, семейство PIC,
семейство ARM Cortex и многие
другие.
Он является автором более 70
технических книг и опубликовал
более 200 технических статей
по электронике,
микропроцессорам,
микроконтроллерам и смежным
областям.
Elektor International Media BV
www.elektor.com