[EN] DAC12 bit with MicroPython

This article describes the working principle of a 2-channel 12-Bit Digital-to-Analog converter module that works with MCP4922 IC with the MicroPython of the ml4m board via the SPI bus to output the analog signal in the triangular waveform. Squares as shown in Figures 6 and 7 of the example in this article.

(Figure. 1 et-mini MCP4922)

Equipment

The equipment in this article includes:

  1. ET-mini MCP4922 or MCP4922 as show in Figure 2.
  2. esp32

MCP4922

Feature

  1. It has the resolution to convert digital values to analog signals in size 12 bits.
  2. There are two analog signal output channels via OUT_A and OUT_B.
  3. The maximum speed of communication via SPI bus is 20MHz.
  4. It takes approximately 45nsec to convert the voltage level or analog signal.
  5. Work with DC voltage at a voltage level of 2V7 to 5V5.
  6. Configurable signal amplification between x1 and x2.

Connection diagram

The connection between MCP4922 and esp32 is as shown in Figure 2.

  • MCP4922’s SCK connected to esp32’s IO18
  • MCP4922’s SDI connected to esp32’s IO23
  • MCP4922’s CS connected to esp32’s IO27
(Figure. 2 Connection between esp32 WROOM and MCP4922)

Pin arrangment

The IC MCP4922 that we use is a 14-pin IC with the pin arrangement as shown in Figure 3.

(Figure. 3 MCP49x2’s pin arrangement)
From

From Figure 3

  • The SDI pin is used to receive data from the microcontroller.
  • CS pin for receiving CS signal.
  • VOUTA pin for output voltage from channel A.
  • VOUTB pin for output voltage from channel B.
  • LDAC pin for sending pulse to output data from buffer to VOUTA or VOUTB.
  • SHDN pin to enable or disable the IC.
  • VREFA and VREFB pins for channel A and B reference voltage.

Flowchart

The working flow diagram is shown in Figure 4, the pin for controlling the operation is the pin SHDN which when set to 0 will cause the module MCP4922 to stop working and if it is 1, it will be activated. You can also enable or disable this function from the following commands. Additionally, the MCP4922 supports 1x (x1) and 2x (x2) voltage boosts determined by the Gain Logic, which is also configured from the instruction bit.

The output voltage level of VOUTA and VOUTB can be set by setting the voltage level from the VREFA and VREFB pins.

(Figure. 4 Workflow diagram of MCP49x2)
From

Timing chart

The timing diagram of the MCP4922 IC is shown in Figure 5. The operation uses the instruction appended to the first 4 bits of data sent to the MOSI pin, which will be discussed in the next section.

(Figure. 5 Timing diagram of MCP49x2)
From

From Figure 5, it has a relationship of working commands: before starting pins CS and LDAC it has a status of 1 and when the module works, it has to change the state of CS to 0. After that, it sends data via SI or MOSI pin of the microcontroller. Runs from the top byte to the last bit of the lowest byte then raises the CS pin back to 1. Now programmers can direct data from the buffer to OUT_A or OUT_B by sending a pulse. 1->0->1 from the LDAC pin or set the LDAC pin to 0 all the time for automatic removal as well.

Commands

Executing the MCP4922 module requires instruction of the upper 4 bits, the upper byte or the 8th to 15th bits to be configured as follows.

Bit15141312111098
DescriptionChannelBufferGain or voltageIC on/off11st bit10th bit9th bit8th bit
value0 is ch A
1 is ch B
0 no buffer
1 buffer
0 voltage x2
1 voltage x1
0 turn off
1 turn on
         

and for the lower byte or bits 0 to 7 is as follows

Bit76543210
Description7th bit6th bit5th bit4th bit3rd bit2nd bit1st bit0th bit

Example Code

Example of a program to send a triangle wave or start from 0 to 4095 and decrease from 4094 to 0. Write the code as follows.

######################################################################
#
# MCP4922 12-bit ADC with SPI Interface
# 
# (C) 2021, JarutEx
#     https://www.jarutex.com
######################################################################
from machine import SPI, Pin, ADC
import time

pinCS = Pin(27, Pin.OUT)
pinCS.on()

spi = SPI(1,baudrate=20000000,sck=Pin(18,Pin.OUT),mosi=Pin(23,Pin.OUT),miso=Pin(19,Pin.IN))

try:
    dacData = 0
    dacDir = 0
    while True:
        x2 = 0b0111000000000000
        x2 |= (dacData & 0b0000111111111111) 
        buffer = x2.to_bytes(2,'big')
        pinCS.off()
        spi.write(buffer)
        pinCS.on()
        if (dacDir):
            dacData -= 1
            if (dacData < 0):
                dacData = 1
                dacDir = 0
        else:
            dacData += 1
            if (dacData > 4095):
                dacData = 4094
                dacDir = 1
        time.sleep_us(10)
except KeyboardInterrupt:
    pass
tmr0.deinit()
spi.deinit()


An example of the result is as shown in Figure 6.

(Figure. 6 Result of the code)

The next example is to create a square wave as shown in Figure 7.

######################################################################
#
# MCP4922 12-bit ADC with SPI Interface
# 
# (C) 2021, JarutEx
#     https://www.jarutex.com
######################################################################
from machine import SPI, Pin, ADC
import time

spi = SPI(1,baudrate=20000000,sck=Pin(18,Pin.OUT),mosi=Pin(23,Pin.OUT),miso=Pin(19,Pin.IN))
pinCS = Pin(27, Pin.OUT)
pinCS.on()

try:
    dacData = 0
    dacDir = 0
    while True:
        dacData = 4000
        x2 = ((dacData & 0b0000111111111111) | 0b0111000000000000)
        buffer = x2.to_bytes(2,'big')
        pinCS.off()
        spi.write(buffer)
        pinCS.on()
        time.sleep_ms(500)
        dacData = 100
        x2 = ((dacData & 0b0000111111111111) | 0b0111000000000000)
        buffer = x2.to_bytes(2,'big')
        pinCS.off()
        spi.write(buffer)
        pinCS.on()
        time.sleep_ms(500)
except KeyboardInterrupt:
    pass
tmr0.deinit()
spi.deinit()



(Figure. 7 Result from the code)

Conclusion

Through this article, our team hopes that readers will be able to apply DAC modules to microcontroller boards in the future. You will find it easy to operate as the MCP4922 provides a simple operation method by configuring the first 4 bits of data sent in the SPI bus to select the channel. Buffering, gaining, and activating or deactivating the channel and have fun with programming.

If you want to talk with us, feel free to leave comments below!!

References

  1. Microchip MCP4922
  2. Data sheet MCP4922
  3. ET-mini MCP4922
  4. ET-mini MCP4922

(C) 2020-2021, By Jarut Busarathid and Danai Jedsadathitikul

Updated 2021-12-03