Skip to content

Commit ff47ba6

Browse files
committed
got all getters/setters working\!
1 parent a5e361f commit ff47ba6

File tree

3 files changed

+160
-19
lines changed

3 files changed

+160
-19
lines changed

adafruit_mcp4728.py

Lines changed: 87 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
__version__ = "0.0.0-auto.0"
4646
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_MCP4728.git"
4747

48+
from struct import pack_into
4849
from time import sleep
4950
import adafruit_bus_device.i2c_device as i2c_device
5051
from adafruit_register.i2c_struct import UnaryStruct
@@ -133,22 +134,18 @@ def _cache_page(self, value, vref, gain, pd):
133134
def _create_channels(self):
134135
raw_registers = self._read_registers()
135136

136-
self.channel_a = Channel(self._cache_page(*raw_registers[0]))
137-
self.channel_b = Channel(self._cache_page(*raw_registers[1]))
138-
self.channel_c = Channel(self._cache_page(*raw_registers[2]))
139-
self.channel_d = Channel(self._cache_page(*raw_registers[3]))
137+
self.channel_a = Channel(self, self._cache_page(*raw_registers[0]), 0)
138+
self.channel_b = Channel(self, self._cache_page(*raw_registers[1]), 1)
139+
self.channel_c = Channel(self, self._cache_page(*raw_registers[2]), 2)
140+
self.channel_d = Channel(self, self._cache_page(*raw_registers[3]), 3)
140141

141142
def _read_registers(self):
142143
buf = bytearray(24)
143144

144145
with self.i2c_device as i2c:
145146
i2c.readinto(buf)
146-
index = 0
147-
for index, value in enumerate(buf):
148-
if index %3 == 0:
149-
print("\n%4s\t"%index, end="")
150-
print("%s %s "%(format(value, '#010b'), hex(value)), end="")
151-
print()
147+
148+
self._print_buffer(buf)
152149

153150
# stride is 6 because we get 6 bytes for each channel; 3 for the output regs
154151
# and 3 for the eeprom. here we only care about the output buffer so we throw out
@@ -161,37 +158,108 @@ def _read_registers(self):
161158

162159
return current_values
163160

161+
def _print_buffer(self, buf):
162+
print()
163+
for index, value in enumerate(buf):
164+
if index %3 == 0:
165+
print("\n%4s\t"%index, end="")
166+
print("%s %s "%(format(value, '#010b'), hex(value)), end="")
167+
print()
168+
169+
170+
def save_settings(self):
171+
"""Saves the currently selected values, Vref, and gain selections for each channel to the EEPROM, setting them as defaults on power up"""
172+
byte_list = []
173+
byte_list += self._generate_bytes_with_flags(self.channel_a)
174+
byte_list += self._generate_bytes_with_flags(self.channel_b)
175+
byte_list += self._generate_bytes_with_flags(self.channel_c)
176+
byte_list += self._generate_bytes_with_flags(self.channel_d)
177+
self._write_multi_eeprom(byte_list)
164178

165179
# TODO: add the ability to set an offset
166180
def _write_multi_eeprom(self, byte_list):
167181
buffer_list = [_MCP4728_CH_A_MULTI_EEPROM]
168182
buffer_list += byte_list
169183

170184
buf = bytearray(buffer_list)
185+
print("buffers to eeprom:")
186+
self._print_buffer(buf)
171187
with self.i2c_device as i2c:
172188
i2c.write(buf)
173189

174190
sleep(0.015) # the better to write you with
175191

192+
def _set_vrefs(self):
193+
base_values = 0b100000000
194+
base_values |= (self.channel_a.vref<<3)
195+
base_values |= (self.channel_b.vref<<2)
196+
base_values |= (self.channel_c.vref<<1)
197+
base_values |= (self.channel_d.vref)
198+
print("VREP VALUES: %s"%(self._lzb(base_values)))
199+
200+
with self.i2c_device as i2c:
201+
i2c.write(bytearray(base_values))
202+
203+
def _set_gains(self):
204+
# [S] 1 1 0 0 A2 A1 A0 0
205+
# [A] 1 1 0 X GXA GXB GXC GXD [A] [P]
206+
base_values = 0b110000000
207+
base_values |= (self.channel_a.gain<<3)
208+
base_values |= (self.channel_b.gain<<2)
209+
base_values |= (self.channel_c.gain<<1)
210+
base_values |= (self.channel_d.gain)
211+
print("GAINZ VALUES: %s"%(self._lzb(base_values)))
212+
213+
with self.i2c_device as i2c:
214+
i2c.write(bytearray(base_values))
215+
216+
def _set_value(self, channel):
217+
218+
channel_bytes = self._generate_bytes_with_flags(channel)
219+
220+
write_command_byte = 0b01000000 # 0 1 0 0 0 DAC1 DAC0 UDAC
221+
write_command_byte |= (channel._channel_index<<1)
222+
223+
channel_bytes.insert(0, write_command_byte)
224+
# print("sending buffer:")
225+
# self._print_buffer(channel_bytes)
226+
with self.i2c_device as i2c:
227+
i2c.write(bytearray(channel_bytes))
228+
229+
def _generate_bytes_with_flags(self, channel):
230+
buf = bytearray(2)
231+
pack_into(">H", buf, 0, channel.raw_value)
232+
# print("Value is ", channel.raw_value)
233+
# print("packed into buffer:")
234+
# self._print_buffer(buf)
235+
236+
buf[0] |= channel.vref << 7
237+
buf[0] |= channel.gain << 4
238+
# print("after setting of flags:")
239+
# self._print_buffer(buf)
240+
return buf
176241

177242
class Channel:
178243
"""An instance of a single channel for a multi-channel DAC"""
179-
def __init__(self, cache_page):
244+
def __init__(self, dac_instance, cache_page, index):
245+
print("Channel", index, "cache_page:", cache_page)
180246
self._vref = cache_page['vref']
181247
self._gain = cache_page['gain']
182248
self._raw_value = cache_page['value']
249+
self._dac = dac_instance
250+
self._channel_index = index
183251

184252
@property
185253
def normalized_value(self):
186254
"""The DAC value as a floating point number in the range 0.0 to 1.0."""
187-
return self._raw_value / (2**12-1)
255+
return self.raw_value / (2**12-1)
188256

189257
@normalized_value.setter
190258
def normalized_value(self, value):
191259
if value < 0.0 or value > 1.0:
192260
raise AttributeError("`normalized_value` must be between 0.0 and 1.0")
193261

194-
self._raw_value = int(value * 4095.0)
262+
self.raw_value = int(value * 4095.0)
195263

196264
@property
197265
def value(self):
@@ -205,7 +273,7 @@ def value(self, value):
205273
raise AttributeError("`value` must be a 16-bit integer between 0 and %s"%(2**16-1))
206274

207275
# Scale from 16-bit to 12-bit value (quantization errors will occur!).
208-
self._raw_value = value >> 4
276+
self.raw_value = value >> 4
209277

210278
@property
211279
def raw_value(self):
@@ -217,6 +285,7 @@ def raw_value(self, value):
217285
if value < 0 or value > (2**12-1):
218286
raise AttributeError("`raw_value` must be a 12-bit integer between 0 and %s"%(2**12-1))
219287
self._raw_value = value
288+
self._dac._set_value(self)
220289

221290
@property
222291
def gain(self):
@@ -227,7 +296,9 @@ def gain(self):
227296
def gain(self, value):
228297
if value < 1 or value > 2:
229298
raise AttributeError("`gain` must be 1 or 2")
230-
self._vref = value
299+
self._gain = value-1
300+
# needs to call gain setter with all gains.
301+
self._dac._set_gains()
231302

232303
@property
233304
def vref(self):
@@ -239,3 +310,4 @@ def vref(self, value):
239310
if value < 0 or value > 3:
240311
raise AttributeError("`vref` must be a ``VREF``")
241312
self._vref = value
313+
self._dac._set_vrefs()

examples/mcp4728_setter_test.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import board
2+
import busio
3+
import adafruit_mcp4728
4+
5+
i2c = busio.I2C(board.SCL, board.SDA)
6+
mcp4728 = adafruit_mcp4728.MCP4728(i2c)
7+
8+
# mcp4728.channel_a.value = 0 # Voltage = VCC
9+
# mcp4728.channel_b.value = 50 # VCC/2
10+
# mcp4728.channel_c.value = 100 # VCC/4
11+
# mcp4728.channel_d.value = 65535 # VCC/8
12+
13+
# mcp4728.channel_a.gain = 2
14+
# mcp4728.channel_b.gain = 2
15+
# mcp4728.channel_c.gain = 2
16+
# mcp4728.channel_d.gain = 2
17+
18+
# mcp4728.channel_a.vref = 0
19+
# mcp4728.channel_b.vref = 0
20+
# mcp4728.channel_c.vref = 0
21+
# mcp4728.channel_d.vref = 0
22+
23+
print("cha value:", mcp4728.channel_a.value)
24+
print("chb value:", mcp4728.channel_b.value)
25+
print("chc value:", mcp4728.channel_c.value)
26+
print("chd value:", mcp4728.channel_d.value)
27+
print()
28+
29+
print("cha gain:", mcp4728.channel_a.gain)
30+
print("chb gain:", mcp4728.channel_b.gain)
31+
print("chc gain:", mcp4728.channel_c.gain)
32+
print("chd gain:", mcp4728.channel_d.gain)
33+
print()
34+
print("cha vref:", mcp4728.channel_a.vref)
35+
print("chb vref:", mcp4728.channel_b.vref)
36+
print("chc vref:", mcp4728.channel_c.vref)
37+
print("chd vref:", mcp4728.channel_d.vref)
38+
39+
40+
# mcp4728.save_settings()

examples/mcp4728_simpletest.py

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,36 @@
55
i2c = busio.I2C(board.SCL, board.SDA)
66
mcp4728 = adafruit_mcp4728.MCP4728(i2c)
77

8-
mcp4728.channel_a.value = 4095 # Voltage = VCC
9-
mcp4728.channel_b.value = 2048 # VCC/2
10-
mcp4728.channel_c.value = 1024 # VCC/4
11-
mcp4728.channel_d.value = 512 # VCC/8
8+
# mcp4728.channel_a.value = 0 # Voltage = VCC
9+
# mcp4728.channel_b.value = 50 # VCC/2
10+
# mcp4728.channel_c.value = 100 # VCC/4
11+
# mcp4728.channel_d.value = 65535 # VCC/8
12+
13+
# mcp4728.channel_a.gain = 2
14+
# mcp4728.channel_b.gain = 2
15+
# mcp4728.channel_c.gain = 2
16+
# mcp4728.channel_d.gain = 2
17+
18+
# mcp4728.channel_a.vref = 0
19+
# mcp4728.channel_b.vref = 0
20+
# mcp4728.channel_c.vref = 0
21+
# mcp4728.channel_d.vref = 0
22+
23+
print("cha value:", mcp4728.channel_a.value)
24+
print("chb value:", mcp4728.channel_b.value)
25+
print("chc value:", mcp4728.channel_c.value)
26+
print("chd value:", mcp4728.channel_d.value)
27+
print()
28+
29+
print("cha gain:", mcp4728.channel_a.gain)
30+
print("chb gain:", mcp4728.channel_b.gain)
31+
print("chc gain:", mcp4728.channel_c.gain)
32+
print("chd gain:", mcp4728.channel_d.gain)
33+
print()
34+
print("cha vref:", mcp4728.channel_a.vref)
35+
print("chb vref:", mcp4728.channel_b.vref)
36+
print("chc vref:", mcp4728.channel_c.vref)
37+
print("chd vref:", mcp4728.channel_d.vref)
38+
39+
40+
# mcp4728.save_settings()

0 commit comments

Comments
 (0)