.. currentmodule:: pyb .. _pyb.DAC: class DAC -- digital to analog conversion ========================================= The DAC outputs analog voltages between 0 V and 3.3 V on one of two STM32 DAC channels. On every STM32 OpenMV Cam that exposes ``pyb.DAC`` (M4 / M7 / H7 / H7 Plus / Pure Thermal) the channels are wired as follows: .. list-table:: :header-rows: 1 :widths: 24 28 48 * - DAC channel - Header pin - STM32 pin * - ``DAC(1)`` - *(not on header)* - ``PA4`` * - ``DAC(2)`` - ``P6`` - ``PA5`` The OpenMV Cam N6 does not have a DAC peripheral; ``pyb.DAC`` is unavailable on that board. Example usage:: from pyb import DAC dac = DAC(1) # create DAC channel 1 dac.write(128) # write a value to the DAC (approximately 1.65 V) dac = DAC(1, bits=12) # use 12-bit resolution dac.write(4095) # output maximum value, 3.3 V To output a continuous sine-wave:: import math from pyb import DAC # create a buffer containing a sine-wave buf = bytearray(100) for i in range(len(buf)): buf[i] = 128 + int(127 * math.sin(2 * math.pi * i / len(buf))) # output the sine-wave at 400Hz dac = DAC(1) dac.write_timed(buf, 400 * len(buf), mode=DAC.CIRCULAR) To output a continuous sine-wave at 12-bit resolution:: import math from array import array from pyb import DAC # 128-sample sine wave, half-word samples centred at 2048 (12-bit mid). N = 128 buf = array("H", ( 2048 + int(2047 * math.sin(2 * math.pi * i / N)) for i in range(N) )) # Output the sine wave at 400Hz. dac = DAC(1, bits=12) dac.write_timed(buf, 400 * len(buf), mode=DAC.CIRCULAR) Constructors ------------ .. class:: DAC(port: Union[int, Pin], bits: int = 8, *, buffering: Optional[bool] = None) Construct a new DAC object. ``port`` can be a :class:`Pin` object, or an integer (``1`` or ``2``) selecting DAC channel 1 or 2. The physical pin each channel is routed to depends on the OpenMV Cam. ``bits`` is an integer specifying the resolution, and can be 8 or 12. The maximum value accepted by :meth:`write` and :meth:`write_timed` is ``(2**bits) - 1`` (255 for 8-bit, 4095 for 12-bit). The *buffering* parameter selects the behaviour of the DAC op-amp output buffer, whose purpose is to reduce the output impedance. It can be ``None`` to select the default (buffering enabled for :meth:`DAC.noise`, :meth:`DAC.triangle` and :meth:`DAC.write_timed`, and disabled for :meth:`DAC.write`), ``False`` to disable buffering completely, or ``True`` to enable output buffering. When buffering is enabled the DAC pin can drive loads down to 5KΩ. Otherwise it has an output impedance of 15KΩ maximum: consequently to achieve a 1% accuracy without buffering requires the applied load to be less than 1.5MΩ. Using the buffer incurs a penalty in accuracy, especially near the extremes of range. Methods ------- .. method:: init(bits: int = 8, *, buffering: Optional[bool] = None) -> None Reinitialise the DAC. *bits* can be 8 or 12. *buffering* can be ``None``, ``False`` or ``True``; see above constructor for the meaning of this parameter. .. method:: deinit() -> None De-initialise the DAC making its pin available for other uses. .. method:: noise(freq: int) -> None Generate a pseudo-random noise signal. A new random sample is written to the DAC output at the given frequency. .. method:: triangle(freq: int) -> None Generate a triangle wave. The value on the DAC output changes at the given frequency and ramps through the full 12-bit range (up and down). Therefore the frequency of the repeating triangle wave itself is 8192 times smaller. .. method:: write(value: int) -> None Direct access to the DAC output. The minimum value is ``0``; the maximum is ``(2**bits) - 1``, where ``bits`` is set when creating the DAC object or via :meth:`init`. .. method:: write_timed(data: Union[bytes, bytearray, "array.array"], freq: Union[int, Timer], *, mode: int = DAC.NORMAL) -> None Initiates a burst of RAM to DAC using a DMA transfer. The input data is treated as an array of bytes in 8-bit mode, and an array of unsigned half-words (array typecode 'H') in 12-bit mode. ``freq`` can be an integer specifying the frequency to write the DAC samples at, using Timer(6). Or it can be an already-initialised Timer object which is used to trigger the DAC sample. Valid timers are 2, 4, 5, 6, 7 and 8. ``mode`` can be ``DAC.NORMAL`` or ``DAC.CIRCULAR``. Example using both DACs at the same time:: dac1 = DAC(1) dac2 = DAC(2) dac1.write_timed(buf1, pyb.Timer(6, freq=100), mode=DAC.CIRCULAR) dac2.write_timed(buf2, pyb.Timer(7, freq=200), mode=DAC.CIRCULAR) Constants --------- .. data:: NORMAL :type: int ``NORMAL`` mode does a single transmission of the waveform in the data buffer. .. data:: CIRCULAR :type: int ``CIRCULAR`` mode transmits the waveform in the data buffer and wraps around to the start of the buffer every time it reaches the end, producing a continuous loop until :meth:`deinit` is called.