Ранее на нашем сайте мы рассмотрели начало работы с платой Raspberry Pi Pico, подключение к ней OLED дисплея и ультразвукового датчика измерения расстояний. В этой же статье мы рассмотрим использование аналого-цифрового преобразования (АЦП) в плате Raspberry Pi Pico. Результаты АЦП будут выводиться на экран OLED дисплея. Программа для проекта будет написана на языке MicroPython.
Плата Raspberry Pi Pico содержит в своем составе 4 АЦП канала с разрешением 12 бит, но один из них подключен к внутреннему датчику температуры. Оставшиеся АЦП канала расположены на контактах GPIO26, GPIO27, GPIO28 и имеют обозначения ADC0, ADC1 и ADC2 соответственно. На следующем рисунке данные АЦП каналы на распиновке платы выделены красным цветом.
Необходимые компоненты
- Плата Raspberry Pi Pico (купить на AliExpress).
- Модуль OLED дисплея SSD1306 128×64 с диагональю 1.3 дюйма и интерфейсом I2C (купить на AliExpress).
- Потенциометр 10 кОм (купить на AliExpress).
- Макетная плата.
- Соединительные провода.
Схема проекта
Схема для демонстрации возможностей аналого-цифрового преобразования (АЦП) в плате Raspberry Pi Pico представлена на следующем рисунке.
Как показано на схеме, потенциометр подключен к контактам 3.3v, GPIO28 и Ground платы Raspberry Pi Pico. Контакты SDA и SCL OLED дисплея подключены к контактам GPIO16 и GPIO17 платы, а контакт VCC OLED дисплея подключен к контакту 3.3v платы. Контакт земли (ground) OLED дисплея подключен к земле (Ground) платы.
Принципы АЦП в плате Raspberry Pi Pico с помощью MicroPython
Итак, в плате Raspberry Pi Pico мы имеем три АЦП канала с разрешением 12 бит. Однако при использовании языка MicroPython мы можем увеличить разрешение этих АЦП каналов до 16 бит. С помощью библиотеки ADC (АЦП) языка MicroPython происходит масштабирование 12-битного разрешения в 16-битное, то есть мы получаем максимальное значение на выходе АЦП 65535 (i.e. 2^16) вместо 4096 (i.e. 2^12) при 12-битном разрешении. В нашем проекте мы подключили потенциометр к контакту GPIO28 платы Raspberry Pi Pico, это значит что мы будем использовать канал АЦП с обозначением ADC2. Напряжение на входе данного контакта может составлять величину от 0V до 3.3V. Для определения значения напряжения на входе АЦП необходимо умножить значение, полученное на выходе АЦП на коэффициент перевода (конверсии).
Прежде чем переходить к программированию, скачайте каталог с кодами программ по этой ссылке с GitHub. В скачанной папке откройте каталог “T3_ADC_on_Pico”, в нем будет два подкаталога - “codes” и “images”. В подкаталоге “codes” вы найдете два файла – “main.py” и “ssd1306.py”. Назначение файла ssd1306.py описано в нашей предыдущей статье про подключение OLED дисплея к плате Raspberry Pi Pico. Здесь же более подробно обсудим содержание файла main.py.
Объяснение программы для Raspberry Pi Pico
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
В файле “main.py” содержатся библиотеки “machine.py” и “ssd1306.py”. Библиотека machine.py – это встроенная в MicroPython библиотека для выполнения базовых операций при работе с интерфейсами I2C, ADC, SPI и т.д. Библиотека ssd1306.py используется для работы с OLED дисплеем. Более подробно про работу с данной библиотекой вы можете прочитать в статье про подключение OLED дисплея к плате Raspberry Pi Pico. Библиотека utime.py используется для организации временных задержек в программе.
1 2 3 |
from machine import Pin, I2C, ADC from ssd1306 import SSD1306_I2C import utime |
Команда machine.ADC(28) используется для определения канала АЦП, расположенного на контакте GPIO28. Коэффициент перевода (conversion_factor) используется для расчета результирующего значения напряжения. Команда I2C(0, scl=Pin(17), sda=Pin(16), freq=200000) используется для инициализации соединения по интерфейсу I2C. Функция SSD1306_I2C() используется для создания oled объекта, который в дальнейшем будет использоваться нами для операций с OLED дисплеем.
1 2 3 4 5 6 |
analog_value = machine.ADC(28) conversion_factor = 3.3 / (65535) WIDTH = 128 # oled display width HEIGHT = 64 # oled display height i2c = I2C(0, scl=Pin(17), sda=Pin(16), freq=200000) # Init I2C using pins GP8 & GP9 (default I2C0 pins) oled = SSD1306_I2C(WIDTH, HEIGHT, i2c) # Init oled display |
В следующем фрагменте кода мы очищаем экран дисплея с помощью функции oled.fill(0). Далее мы подготавливаем вывод нескольких строк текста на экран дисплея с помощью функции oled.text() и окончательно отображаем их на экране дисплея с помощью функции oled.show().
1 2 3 4 5 6 7 8 9 |
# Clear the oled display in case it has junk on it. oled.fill(0) # Add some text oled.text("CIRCUIT",5,8) oled.text("DIGEST",45,18) oled.text("ADC",28,40) # Finally update the oled display so the image & text is displayed oled.show() utime.sleep(1) |
Далее в цикле while мы считываем значение с выхода АЦП на контакте GPIO28 с помощью функции analog_value.read_u16() и сохраняем его в переменной reading. Значение с выхода АЦП мы в данном случае получаем в разрешение 16 бит, поскольку, как это уже упоминалось, эта опция доступна в языке MicroPython. Далее мы это считанное значение умножаем на коэффициент перевода (conversion_factor) чтобы получить истинное значение напряжение. Определенное значение напряжения voltageValue затем мы отображаем на экране дисплея с помощью функции oled.text().
1 2 3 4 5 6 7 8 9 10 |
while True: oled.fill(0) reading = analog_value.read_u16() print("ADC: ",reading) utime.sleep(0.2) voltageValue = reading* conversion_factor oled.text("Voltage:",5,8) oled.text(str(voltageValue)+"V",15,25) oled.show() utime.sleep(1) |
Для тестирования работы проекта откройте файлы “main.py” и “ssd1306.py” в Thonny IDE. Чтобы сохранить файл “ssd1306.py” на плату Raspberry Pi Pico нажмите комбинацию клавиш “ctrl+shift+s” на клавиатуре. Убедитесь в том, что ваша плата подключена в это время к компьютеру. При сохранении кода программы откроется всплывающее окно, показанное на рисунке ниже. В этом окне вам необходимо выбрать Raspberry Pi Pico, после этого сохранить код программы под именем "ssd1306.py". Аналогичную процедуру необходимо повторить и для файла “main.py”. После этого вы сможете запускать эти программы на плате всегда, когда на нее подано питание.
Исходный код программы на MicroPython
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# Display Image & text on I2C driven ssd1306 OLED display from machine import Pin, I2C, ADC from ssd1306 import SSD1306_I2C import utime analog_value = machine.ADC(28) conversion_factor = 3.3 / (65535) WIDTH = 128 # oled display width HEIGHT = 64 # oled display height i2c = I2C(0, scl=Pin(17), sda=Pin(16), freq=200000) # Init I2C using pins GP8 & GP9 (default I2C0 pins) print("I2C Address : "+hex(i2c.scan()[0]).upper()) # отображение адреса устройства print("I2C Configuration: "+str(i2c)) # отображение конфигурации I2C oled = SSD1306_I2C(WIDTH, HEIGHT, i2c) # инициализация oled дисплея # Clear the oled display in case it has junk on it. (очищаем экран дисплея) oled.fill(0) # Add some text (подготавливаем текст для вывода на экран) oled.text("CIRCUIT",5,8) oled.text("DIGEST",45,18) oled.text("ADC",28,40) # Finally update the oled display so the image & text is displayed (выводим текст на экран дисплея) oled.show() utime.sleep(1) while True: oled.fill(0) reading = analog_value.read_u16() print("ADC: ",reading) utime.sleep(0.2) voltageValue = reading* conversion_factor oled.text("Voltage:",5,8) oled.text(str(voltageValue)+"V",15,25) oled.show() utime.sleep(1) |