1
+ # -*- encoding: utf-8 -*-
2
+ '''
3
+ @File : _dac2.py
4
+ @Time : 2023/12/27
5
+ @Author : TONG YIHAN
6
+
7
+ @License : (C)Copyright 2015-2023, M5STACK
8
+ '''
9
+
10
+ # Import necessary libraries
11
+ from machine import I2C
12
+ from .pahub import PAHUBUnit
13
+ from .unit_helper import UnitError
14
+ import struct
15
+ import sys
16
+
17
+ if sys .platform != "esp32" :
18
+ from typing import Union
19
+
20
+
21
+ class DAC2Unit :
22
+ """! DAC2 is a Digital to Analog Converter, GP8413 15bit DAC.
23
+
24
+ @en DAC2 is a Digital to Analog Converter, includes GP8413 15bit DAC. The GP8413, through the I2C interface, linearly converts to two channels of analog voltage output, 0-5V and 0-10V.
25
+ @cn DAC2 是一个数字模拟转换器,包含GP8413 15位DAC。GP8413通过I2C接口线性转换为两个通道的模拟电压输出,0-5V和0-10V。
26
+
27
+ @attr RANGE_5V output from 0 to 5V
28
+ @attr RANGE_10V output from 0 to 10V
29
+ @color #0FE6D7
30
+ @link https://docs.m5stack.com/en/unit/dac
31
+ @image https://static-cdn.m5stack.com/resource/docs/products/unit/dac/dac_01.webp
32
+ """
33
+ RANGE_5V = 0
34
+ RANGE_10V = 1
35
+ CHANNEL_0 = 0 ,
36
+ CHANNEL_1 = 1 ,
37
+ CHANNEL_BOTH = 2 ,
38
+
39
+ def __init__ (self , i2c : Union [I2C , PAHUBUnit ], addr = 0x59 ):
40
+ """! Initialize the DAC.
41
+
42
+ @param port I2C port to use.
43
+ @param addr I2C address of the sensor.
44
+ """
45
+ self .i2c = i2c
46
+ self .addr = addr
47
+ self ._available ()
48
+ self ._range = self .RANGE_5V
49
+ self .setDACOutputVoltageRange (self ._range )
50
+
51
+ def _available (self ):
52
+ """! Check if sensor is available on the I2C bus.
53
+
54
+ Raises:
55
+ Exception: If the sensor is not found.
56
+ """
57
+ if not (self .addr in self .i2c .scan ()):
58
+ raise UnitError ("DAC2 Unit not found." )
59
+
60
+ def setDACOutputVoltageRange (self , _range : int = 0 ):
61
+ """!
62
+
63
+ @en Set the DAC %1 output voltage range to %2.
64
+ @cn 设置DAC %1 输出电压范围为 %2。
65
+
66
+ @param range The DAC range to set.
67
+ """
68
+ data = 0x00
69
+ self ._range = _range
70
+ if _range == self .RANGE_5V :
71
+ self .i2c .writeto_mem (self .addr , 0x01 , struct .pack ('b' , data ))
72
+ else : # _range == self.RANGE_10V:
73
+ data = 0x11
74
+ self .i2c .writeto_mem (self .addr , 0x01 , struct .pack ('b' , data ))
75
+
76
+ def setVoltage (self , voltage : float , channel : int = 2 ):
77
+ """!
78
+ @en Set %1 channel %3 to %2 V.
79
+ @cn 设置DAC %1 通道 %3 的输出电压为 %1 V。
80
+
81
+ @param voltage The DAC voltage to set, from 0.0 to range.
82
+ @param channel [field_dropdown] The DAC channel to set.
83
+ @options {
84
+ [Channel 0, CHANNEL_0]
85
+ [Channel 1, CHANNEL_1]
86
+ [Both Channel, CHANNEL_BOTH]
87
+ }
88
+ """
89
+ if self ._range == self .RANGE_5V :
90
+ max_voltage = 5.0
91
+ else : # self._range == self.RANGE_10V:
92
+ max_voltage = 10.0
93
+ if voltage > max_voltage :
94
+ voltage = max_voltage
95
+ elif voltage < 0.0 :
96
+ voltage = 0.0
97
+ data = int ((voltage / max_voltage ) * 0xFFFF )
98
+ if channel == self .CHANNEL_BOTH :
99
+ self .i2c .writeto_mem (self .addr , 0x02 , struct .pack ('<HH' , data , data ))
100
+ elif channel == self .CHANNEL_0 :
101
+ self .i2c .writeto_mem (self .addr , 0x02 , struct .pack ('<H' , data ))
102
+ elif channel == self .CHANNEL_1 :
103
+ self .i2c .writeto_mem (self .addr , 0x04 , struct .pack ('<H' , data ))
104
+
105
+ def setVoltageBoth (self , voltage0 : float , voltage1 : float ):
106
+ """!
107
+ @en Set the DAC %1 channel 0 %2 V, channel 1 %3 V.
108
+ @cn 设置 %1 通道0的电压为 %2 V,通道1的电压为 %3 V。
109
+
110
+ @param voltage0 The DAC voltage of channel 0 to set.
111
+ @param voltage1 The DAC voltage of channel 1 to set.
112
+ """
113
+
114
+ if self ._range == self .RANGE_5V :
115
+ max_voltage = 5.0
116
+ else : # self._range == self.RANGE_10V:
117
+ max_voltage = 10.0
118
+ if voltage0 > max_voltage :
119
+ voltage0 = max_voltage
120
+ elif voltage0 < 0.0 :
121
+ voltage0 = 0.0
122
+ if voltage1 > max_voltage :
123
+ voltage1 = max_voltage
124
+ elif voltage1 < 0.0 :
125
+ voltage1 = 0.0
126
+ data0 = int ((voltage0 / max_voltage ) * 0xFFFF )
127
+ data1 = int ((voltage1 / max_voltage ) * 0xFFFF )
128
+ self .i2c .writeto_mem (self .addr , 0x02 , struct .pack ('<HH' , data0 , data1 ))
0 commit comments