MicroPython:Библиотеки/pyb/Класс ADC: различия между версиями

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску
(Новая страница: «{{MicroPython/Панель перехода}} {{Перевод от Сubewriter}} {{Myagkij-редактор}} =<ref>[]</ref>= <syntaxhighlight lang="python"...»)
 
Нет описания правки
Строка 3: Строка 3:
{{Myagkij-редактор}}
{{Myagkij-редактор}}


=<ref>[]</ref>=
=Класс ADC – аналогово-цифровое преобразование<ref>[http://docs.micropython.org/en/latest/library/pyb.ADC.html docs.micropython.org - class ADC – analog to digital conversion]</ref>=


Как пользоваться:


<syntaxhighlight lang="python" enclose="div">
import pyb
adc = pyb.ADC(pin)                  # создает аналоговый объект
                                    # на контакте «pin»
val = adc.read()                    # считывает аналоговое значение
adc = pyb.ADCAll(resolution)        # создает объект «ADCAll»
adc = pyb.ADCAll(resolution, mask)  # создает объект «ADCAll» на
                                    # выбранных аналоговых каналах
val = adc.read_channel(channel)    # считывает заданный канал
val = adc.read_core_temp()          # считывает температуру MCU
val = adc.read_core_vbat()          # считывает напряжение
                                    # резервной батарейки (VBAT) MCU
val = adc.read_core_vref()          # считывает опорное напряжение MCU
val = adc.read_vref()              # считывает питающее
                                    # напряжение MCU
</syntaxhighlight>
==Конструкторы==
* [[MicroPython:Библиотеки/pyb/Класс ADC/pyb.ADC()|pyb.ADC()]]
* pyb.ADC(pin) – создает объект ADC, связанный с заданным контактом. В дальнейшем это позволит считывать аналоговые значения на этом контакте.
== Методы ==
* ADC.read() – считывает значение на аналоговом контакте и возвращает его. Возвращаемое значение будет варьироваться между «0» и «4095».
* ADC.read_timed(buf, timer) – считывает аналоговые значения в буфер buf с периодичностью, заданной в аргументе timer.
Значение в аргументе buf может быть, например, массивом байтов или array.array. АЦП-значения имеют 12-битное разрешение и сохраняются напрямую в буфер buf, если размер его элементов составляет 16 бит или больше. Если в буфере buf только 8-битные элементы (например, это массив байтов), то разрешение данных будет снижено до 8 бит.
В аргументе timer должен быть объект Timer – данные будут считываться при каждом срабатывании этого таймера. Объект Timer должен быть уже инициализирован и запущен с нужной частотой.
В целях совместимости с тем, как эта функция работала раньше, в timer также можно задать целое число, обозначающее частоту (в герцах), с которой нужно считывать данные. В этом случае таймер 6 будет автоматически настроен на эту частоту.
Пример использования объекта Timer (предпочтительный вариант):
<syntaxhighlight lang="python" enclose="div">
adc = pyb.ADC(pyb.Pin.board.X19) # создает объект ADC
                                # на контакте X19
tim = pyb.Timer(6, freq=10)      # создает таймер,
                                # работающий с частотой 10 Гц
buf = bytearray(100)            # создает буфер
                                # для хранения данных
adc.read_timed(buf, tim)        # делаем 100 считываний,
                                # это займет 10 секунд
</syntaxhighlight>
Пример использования целого числа, чтобы задать частоту считывания:
<syntaxhighlight lang="python" enclose="div">
adc = pyb.ADC(pyb.Pin.board.X19) # создаем объект «ADC»
                                # на контакте X19
buf = bytearray(100)            # создаем буфер из 100 байтов
adc.read_timed(buf, 10)          # считываем аналоговые значения
                                # в буфер с частотой 10 Гц;
                                # это займет 10 секунд
for val in buf:                  # пробегаемся по всем данным
    print(val)                  # печатаем данные
</syntaxhighlight>
Эта функция не выделяет память в куче. И это блокирующая функция: программа, запустившая ее, не возобновит работу, пока буфер не заполнится.
* ADC.read_timed_multi((adcx, adcy, ...), (bufx, bufy, ...), timer) – это статический метод. Его можно использовать, чтобы узнать разницу во времени между считываниями на разных АЦП-каналах, а также чтобы прочесть фазовые данные на нескольких АЦП-каналах.
Этот метод считывает аналоговые значения с нескольких АЦП-каналов в буферы с периодичностью, заданной в аргументе timer. При каждом срабатывании таймера с каждого АЦП-канала по очереди быстро считывается новая порция данных.
Экземпляры для АЦП-каналов и буферов передаются в функцию в виде кортежей, в результате чего у каждого АЦП-канала будет привязанный к нему буфер. Все буферы должны быть одного и того же типа и размера, а количество буферов должно соответствовать количеству АЦП-каналов.
Объектами для буферов могут быть, к примеру, bytearray или array.array. АЦП-значения имеют 12-битное разрешение и сохраняются напрямую в буфер, если размер его элементов составляет 16 бит и более. Если в буферах есть только 8-битные элементы (например, bytearray), то разрешение считанных данных будет обрезано до 8 бит.
В аргументе timer должен быть объект Timer. Таймер должен быть уже инициализирован и запущен с нужной частотой.
Пример считывания с трех АЦП-каналов:
<syntaxhighlight lang="python" enclose="div">
adc0 = pyb.ADC(pyb.Pin.board.X1)    # создаем АЦП-каналы
adc1 = pyb.ADC(pyb.Pin.board.X2)
adc2 = pyb.ADC(pyb.Pin.board.X3)
tim = pyb.Timer(8, freq=100)        # создаем таймер
rx0 = array.array('H', (0 for i in range(100))) # АЦП-буферы
rx1 = array.array('H', (0 for i in range(100))) # на 100
                                                # 16-битных слов
rx2 = array.array('H', (0 for i in range(100)))
# считываем аналоговые значения в буферы
# с частотой 100 Гц (занимает одну секунду):
pyb.ADC.read_timed_multi((adc0, adc1, adc2), (rx0, rx1, rx2), tim)
for n in range(len(rx0)):
    print(rx0[n], rx1[n], rx2[n])
</syntaxhighlight>
Эта функция не выделяет память в куче. И это блокирующая функция: программа, запустившая ее, не возобновит работу, пока буфер не заполнится.
Функция вернет True, если все данные были в правильное время. На высоких частотах время считывания может превышать значение в timer – в этом случае функция вернет False, что будет говорить о потере точности данных в период их считывания. В крайнем случае данные могут быть даже потеряны.
Максимальная частота зависит от ряда факторов, включая разрядность данных и количество АЦП-каналов, с которых производится считывание. Согласно нашим тестам, при считывании данных с двух АЦП-каналов с частотой до 210 КГц сбоев не возникает. При частоте 215 КГц данные начинают теряться. Для трех АЦП-каналов это ограничение составляет около 140 КГц, а для четырех – около 110 КГц. На высоких частотах риск случайной потери данных может можно снизить, отключив прерывания на период считывания данных.
== Объект «ADCA11» ==
Инстанцинирование этого объекта переводит все выбранные [[АЦП-контакт]]ы в режим ввода аналоговых данных. Доступ к предварительно обработанным данным о температуре [[микроконтроллер]]а, а также ''VREF'' и ''VBAT'' можно получить на [[АЦП-канал]]ах ''16'', ''17'' и ''18'' соответственно. Масштабирование данных выполняется с помощью опорного напряжения (обычно ''3.3 вольта''). Температурный датчик на чипе имеет заводскую калибровку и позволяет считывать его температуру с точностью ''+/- 1 градус'' по Цельсию. На первый взгляд кажется, что это хорошая точность, но не забывайте, что этот датчик замеряет внутреннюю температуру [[микроконтроллер]]а. В зависимости от вычислительной нагрузки и активности I/O-подсистем, температура чипа может быть запросто на десятки градусов выше окружающей температуры. Другими словами, если вывести [[PyBoard]] из долгого пребывания в режиме простоя, она покажет корректную окружающую температуру, но с учетом условий, обозначенных выше.
Методы read_core_vbat(), read_vref() и read_core_vref() объекта ''ADCA11'' считывают, соответственно, напряжение резервной батареи, опорное напряжение и опорное напряжение, основанное на питающем напряжении (обычно это ''1.21 вольт''). Результат всех трех функций – это напряжение постоянного тока в виде чисел с плавающей точкой.
Функция read_core_vbat() возвращает напряжение резервной батареи. Это напряжение тоже настраивается согласно питающему напряжению. Чтобы не допустить перегрузки на входных аналоговых контактах, напряжение резервной батареи измеряется через делитель напряжения и масштабируется согласно значению этого делителя. Чтобы не допустить чрезмерной нагрузки на резервную батарею, делитель напряжения активен только во время АЦП-операций.
Функция read_vref() измеряет внутреннее опорное напряжение и выполняет обратное масштабирование полученного значения при помощи заводского калибровочного значения внутреннего опорного напряжения. В большинстве случаев результат будет близок к 3.3 вольтам. Если PyBoard работает от батареи, питающее напряжение может упасть ниже 3.3 вольт. PyBoard будет по-прежнему работать нормально – до тех пор, пока будут соблюдены операционные условия. При правильных частоте микроконтроллера, скорости доступа к flash-памяти и режиме программирования PyBoard может работать даже на 2 вольтах и по-прежнему выполнять нормальное аналогово-цифровое преобразование.
Очень важно убедиться, чтобы напряжение на входных аналоговых контактах никогда не превышало питающее напряжение.
Другие входные аналоговые каналы (0-15) возвращают немасштабированные целые числа в соответствии с выбранной точностью.
Чтобы избежать нежелательной активации входных аналоговых каналов (0-15), в этой функции можно задать второй аргумент. Значением в нем служит двоичный паттерн, в котором каждый запрошенный входной аналоговый контакт имеет соответствующий набор битов. Значение по умолчанию – ''«0xffffffff»'', которое означает, что активны все входные аналоговые каналы. Если вам нужны только внутренние каналы (16-18), в этом масочном паттерне должно быть значение ''«0x70000»''.
Пример:


<syntaxhighlight lang="python" enclose="div">
<syntaxhighlight lang="python" enclose="div">
adcall = pyb.ADCAll(12, 0x70000) # 12-битное разрешение,
                                # внутренние каналы
temp = adcall.read_core_temp()
</syntaxhighlight>


=См.также=
=См.также=

Версия от 17:35, 4 октября 2020

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


Класс ADC – аналогово-цифровое преобразование[1]

Как пользоваться:

import pyb

adc = pyb.ADC(pin)                  # создает аналоговый объект
                                    # на контакте «pin»
val = adc.read()                    # считывает аналоговое значение 

adc = pyb.ADCAll(resolution)        # создает объект «ADCAll»
adc = pyb.ADCAll(resolution, mask)  # создает объект «ADCAll» на
                                    # выбранных аналоговых каналах 
val = adc.read_channel(channel)     # считывает заданный канал
val = adc.read_core_temp()          # считывает температуру MCU 
val = adc.read_core_vbat()          # считывает напряжение
                                    # резервной батарейки (VBAT) MCU
val = adc.read_core_vref()          # считывает опорное напряжение MCU 
val = adc.read_vref()               # считывает питающее
                                    # напряжение MCU

Конструкторы

  • pyb.ADC(pin) – создает объект ADC, связанный с заданным контактом. В дальнейшем это позволит считывать аналоговые значения на этом контакте.

Методы

  • ADC.read() – считывает значение на аналоговом контакте и возвращает его. Возвращаемое значение будет варьироваться между «0» и «4095».
  • ADC.read_timed(buf, timer) – считывает аналоговые значения в буфер buf с периодичностью, заданной в аргументе timer.

Значение в аргументе buf может быть, например, массивом байтов или array.array. АЦП-значения имеют 12-битное разрешение и сохраняются напрямую в буфер buf, если размер его элементов составляет 16 бит или больше. Если в буфере buf только 8-битные элементы (например, это массив байтов), то разрешение данных будет снижено до 8 бит. В аргументе timer должен быть объект Timer – данные будут считываться при каждом срабатывании этого таймера. Объект Timer должен быть уже инициализирован и запущен с нужной частотой. В целях совместимости с тем, как эта функция работала раньше, в timer также можно задать целое число, обозначающее частоту (в герцах), с которой нужно считывать данные. В этом случае таймер 6 будет автоматически настроен на эту частоту. Пример использования объекта Timer (предпочтительный вариант):

adc = pyb.ADC(pyb.Pin.board.X19) # создает объект ADC
                                 # на контакте X19
tim = pyb.Timer(6, freq=10)      # создает таймер,
                                 # работающий с частотой 10 Гц 
buf = bytearray(100)             # создает буфер
                                 # для хранения данных
adc.read_timed(buf, tim)         # делаем 100 считываний,
                                 # это займет 10 секунд

Пример использования целого числа, чтобы задать частоту считывания:

adc = pyb.ADC(pyb.Pin.board.X19) # создаем объект «ADC»
                                 # на контакте X19
buf = bytearray(100)             # создаем буфер из 100 байтов 
adc.read_timed(buf, 10)          # считываем аналоговые значения
                                 # в буфер с частотой 10 Гц;
                                 # это займет 10 секунд
for val in buf:                  # пробегаемся по всем данным 
    print(val)                   # печатаем данные

Эта функция не выделяет память в куче. И это блокирующая функция: программа, запустившая ее, не возобновит работу, пока буфер не заполнится.

  • ADC.read_timed_multi((adcx, adcy, ...), (bufx, bufy, ...), timer) – это статический метод. Его можно использовать, чтобы узнать разницу во времени между считываниями на разных АЦП-каналах, а также чтобы прочесть фазовые данные на нескольких АЦП-каналах.

Этот метод считывает аналоговые значения с нескольких АЦП-каналов в буферы с периодичностью, заданной в аргументе timer. При каждом срабатывании таймера с каждого АЦП-канала по очереди быстро считывается новая порция данных. Экземпляры для АЦП-каналов и буферов передаются в функцию в виде кортежей, в результате чего у каждого АЦП-канала будет привязанный к нему буфер. Все буферы должны быть одного и того же типа и размера, а количество буферов должно соответствовать количеству АЦП-каналов. Объектами для буферов могут быть, к примеру, bytearray или array.array. АЦП-значения имеют 12-битное разрешение и сохраняются напрямую в буфер, если размер его элементов составляет 16 бит и более. Если в буферах есть только 8-битные элементы (например, bytearray), то разрешение считанных данных будет обрезано до 8 бит. В аргументе timer должен быть объект Timer. Таймер должен быть уже инициализирован и запущен с нужной частотой. Пример считывания с трех АЦП-каналов:

adc0 = pyb.ADC(pyb.Pin.board.X1)    # создаем АЦП-каналы
adc1 = pyb.ADC(pyb.Pin.board.X2)
adc2 = pyb.ADC(pyb.Pin.board.X3)
tim = pyb.Timer(8, freq=100)        # создаем таймер
rx0 = array.array('H', (0 for i in range(100))) # АЦП-буферы
rx1 = array.array('H', (0 for i in range(100))) # на 100 
                                                # 16-битных слов 
rx2 = array.array('H', (0 for i in range(100)))
# считываем аналоговые значения в буферы 
# с частотой 100 Гц (занимает одну секунду):
pyb.ADC.read_timed_multi((adc0, adc1, adc2), (rx0, rx1, rx2), tim)
for n in range(len(rx0)):
    print(rx0[n], rx1[n], rx2[n])

Эта функция не выделяет память в куче. И это блокирующая функция: программа, запустившая ее, не возобновит работу, пока буфер не заполнится. Функция вернет True, если все данные были в правильное время. На высоких частотах время считывания может превышать значение в timer – в этом случае функция вернет False, что будет говорить о потере точности данных в период их считывания. В крайнем случае данные могут быть даже потеряны. Максимальная частота зависит от ряда факторов, включая разрядность данных и количество АЦП-каналов, с которых производится считывание. Согласно нашим тестам, при считывании данных с двух АЦП-каналов с частотой до 210 КГц сбоев не возникает. При частоте 215 КГц данные начинают теряться. Для трех АЦП-каналов это ограничение составляет около 140 КГц, а для четырех – около 110 КГц. На высоких частотах риск случайной потери данных может можно снизить, отключив прерывания на период считывания данных.

Объект «ADCA11»

Инстанцинирование этого объекта переводит все выбранные АЦП-контакты в режим ввода аналоговых данных. Доступ к предварительно обработанным данным о температуре микроконтроллера, а также VREF и VBAT можно получить на АЦП-каналах 16, 17 и 18 соответственно. Масштабирование данных выполняется с помощью опорного напряжения (обычно 3.3 вольта). Температурный датчик на чипе имеет заводскую калибровку и позволяет считывать его температуру с точностью +/- 1 градус по Цельсию. На первый взгляд кажется, что это хорошая точность, но не забывайте, что этот датчик замеряет внутреннюю температуру микроконтроллера. В зависимости от вычислительной нагрузки и активности I/O-подсистем, температура чипа может быть запросто на десятки градусов выше окружающей температуры. Другими словами, если вывести PyBoard из долгого пребывания в режиме простоя, она покажет корректную окружающую температуру, но с учетом условий, обозначенных выше.

Методы read_core_vbat(), read_vref() и read_core_vref() объекта ADCA11 считывают, соответственно, напряжение резервной батареи, опорное напряжение и опорное напряжение, основанное на питающем напряжении (обычно это 1.21 вольт). Результат всех трех функций – это напряжение постоянного тока в виде чисел с плавающей точкой.

Функция read_core_vbat() возвращает напряжение резервной батареи. Это напряжение тоже настраивается согласно питающему напряжению. Чтобы не допустить перегрузки на входных аналоговых контактах, напряжение резервной батареи измеряется через делитель напряжения и масштабируется согласно значению этого делителя. Чтобы не допустить чрезмерной нагрузки на резервную батарею, делитель напряжения активен только во время АЦП-операций.

Функция read_vref() измеряет внутреннее опорное напряжение и выполняет обратное масштабирование полученного значения при помощи заводского калибровочного значения внутреннего опорного напряжения. В большинстве случаев результат будет близок к 3.3 вольтам. Если PyBoard работает от батареи, питающее напряжение может упасть ниже 3.3 вольт. PyBoard будет по-прежнему работать нормально – до тех пор, пока будут соблюдены операционные условия. При правильных частоте микроконтроллера, скорости доступа к flash-памяти и режиме программирования PyBoard может работать даже на 2 вольтах и по-прежнему выполнять нормальное аналогово-цифровое преобразование. Очень важно убедиться, чтобы напряжение на входных аналоговых контактах никогда не превышало питающее напряжение.

Другие входные аналоговые каналы (0-15) возвращают немасштабированные целые числа в соответствии с выбранной точностью.

Чтобы избежать нежелательной активации входных аналоговых каналов (0-15), в этой функции можно задать второй аргумент. Значением в нем служит двоичный паттерн, в котором каждый запрошенный входной аналоговый контакт имеет соответствующий набор битов. Значение по умолчанию – «0xffffffff», которое означает, что активны все входные аналоговые каналы. Если вам нужны только внутренние каналы (16-18), в этом масочном паттерне должно быть значение «0x70000».

Пример:

adcall = pyb.ADCAll(12, 0x70000) # 12-битное разрешение, 
                                 # внутренние каналы
temp = adcall.read_core_temp()

См.также

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