Skip to content

Commit d9330c7

Browse files
authored
Add files via upload
1 parent ab7fa75 commit d9330c7

File tree

6 files changed

+40377
-0
lines changed

6 files changed

+40377
-0
lines changed

Clue_Scale/clue_scale_bkg.bmp

225 KB
Binary file not shown.
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# SPDX-FileCopyrightText: 2022 Jan Goolsbey for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
3+
#
4+
# clue_scale_calibrator.py
5+
# 2022-07-29 v1.1.0
6+
#
7+
# Clue Scale Calibrator - Single Channel Version
8+
# Adafruit NAU7802 Stemma breakout example
9+
10+
import time
11+
import board
12+
from adafruit_clue import clue
13+
from cedargrove_nau7802 import NAU7802
14+
15+
clue.pixel.brightness = 0.2 # Set NeoPixel brightness
16+
clue.pixel[0] = clue.YELLOW # Set status indicator to yellow (initializing)
17+
18+
SAMPLE_AVG = 500 # Number of sample values to average
19+
DEFAULT_GAIN = 128 # Default gain for internal PGA
20+
21+
# Instantiate 24-bit load sensor ADC
22+
nau7802 = NAU7802(board.I2C(), address=0x2A, active_channels=1)
23+
24+
25+
def zero_channel():
26+
"""Initiate internal calibration and zero the current channel. Use after
27+
power-up, a new channel is selected, or to adjust for measurement drift.
28+
Can be used to zero the scale with a tare weight."""
29+
nau7802.calibrate("INTERNAL")
30+
nau7802.calibrate("OFFSET")
31+
32+
33+
def read(samples=100):
34+
# Read and average consecutive raw sample values; return average raw value
35+
sample_sum = 0
36+
sample_count = samples
37+
while sample_count > 0:
38+
if nau7802.available:
39+
sample_sum = sample_sum + nau7802.read()
40+
sample_count -= 1
41+
return int(sample_sum / samples)
42+
43+
44+
# Activate the NAU780 internal analog circuitry, set gain, and calibrate/zero
45+
nau7802.enable(True)
46+
nau7802.gain = DEFAULT_GAIN # Use default gain
47+
zero_channel() # Calibrate and zero
48+
49+
print("-----------------------------------")
50+
print(" NAU7802 SINGLE CHANNEL CALIBRATOR")
51+
print("-----------------------------------")
52+
print("Place a calibration weight on the")
53+
print("load cell.")
54+
print("To re-zero the load cell, remove")
55+
print("any weights then press and hold A.")
56+
print("-----------------------------------")
57+
print("")
58+
59+
# Play "welcome" tones
60+
clue.play_tone(1660, 0.15)
61+
clue.play_tone(1440, 0.15)
62+
63+
# Main loop: Read sample and display value
64+
while True:
65+
clue.pixel[0] = clue.GREEN # Set status indicator to green
66+
67+
# Read the raw value; print raw value, gain setting, and % of full-scale
68+
value = read(SAMPLE_AVG)
69+
print(f"CHAN_{nau7802.channel:1.0f} RAW VALUE: {value:7.0f}")
70+
print(f"GAIN: x{DEFAULT_GAIN} full-scale: {(value / ((2**23) - 1)) * 100:3.2f}%")
71+
print("===================================")
72+
73+
time.sleep(0.1)
74+
75+
if clue.button_a:
76+
# Zero and recalibrate the NAU780
77+
clue.play_tone(1660, 0.3) # Play "button pressed" tone
78+
clue.pixel[0] = clue.RED # Set status indicator to red (stopped)
79+
zero_channel()
80+
while clue.button_a:
81+
# Wait until button is released
82+
time.sleep(0.1)
83+
print("RECALIBRATED")
84+
clue.play_tone(1440, 0.5) # Play "reset completed" tone

Clue_Scale/code.py

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# SPDX-FileCopyrightText: 2022 Jan Goolsbey for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
3+
#
4+
# clue_scale_code.py
5+
# 2022-07-29 v1.2.0
6+
#
7+
# Clue Scale - Single Channel Version
8+
# Adafruit NAU7802 Stemma breakout example
9+
10+
# import clue_scale_calibrator # Uncomment to run calibrator method
11+
12+
import time
13+
import board
14+
from simpleio import map_range
15+
from adafruit_clue import clue
16+
from adafruit_display_shapes.circle import Circle
17+
from adafruit_display_text.label import Label
18+
from adafruit_bitmap_font import bitmap_font
19+
import displayio
20+
from cedargrove_nau7802 import NAU7802
21+
22+
clue.pixel.brightness = 0.2 # Set NeoPixel brightness
23+
clue.pixel[0] = clue.YELLOW # Set status indicator to yellow (initializing)
24+
25+
# Set Scale Defaults
26+
MAX_GR = 100 # Maximum (full-scale) display range in grams
27+
DEFAULT_GAIN = 128 # Default gain for internal PGA
28+
SAMPLE_AVG = 100 # Number of sample values to average
29+
SCALE_NAME_1 = "COFFEE" # 6 characters maximum
30+
SCALE_NAME_2 = "SCALE" # 6 characters maximum
31+
32+
"""Enter the calibration ratio for the individual load cell in-use. The ratio is
33+
composed of the reference weight in grams divided by the raw reading. For
34+
example, a raw reading of 215300 for a 100 gram weight results in a calibration
35+
ratio of 100 / 215300. Use the clue_scale_single_calibrate method to obtain the
36+
raw value.
37+
FYI: A US dime coin weighs 2.268 grams or 0.079 ounces."""
38+
CALIB_RATIO = 100 / 215300 # load cell serial#4540-02
39+
40+
# Instantiate the Sensor and Display
41+
nau7802 = NAU7802(board.I2C(), address=0x2A, active_channels=1)
42+
43+
display = board.DISPLAY
44+
scale_group = displayio.Group()
45+
46+
FONT_0 = bitmap_font.load_font("/fonts/Helvetica-Bold-24.bdf")
47+
FONT_1 = bitmap_font.load_font("/fonts/OpenSans-16.bdf")
48+
FONT_2 = bitmap_font.load_font("/fonts/OpenSans-9.bdf")
49+
50+
# Display the Background Bitmap Image
51+
bkg = displayio.OnDiskBitmap("/clue_scale_bkg.bmp")
52+
_background = displayio.TileGrid(bkg, pixel_shader=bkg.pixel_shader, x=0, y=0)
53+
scale_group.append(_background)
54+
55+
# Define and Display the Text Labels and Graphic Elements
56+
# Place the project name on either side of the graduated scale
57+
scale_name_1 = Label(FONT_1, text=SCALE_NAME_1, color=clue.CYAN)
58+
scale_name_1.anchor_point = (0.5, 0.5)
59+
scale_name_1.anchored_position = (40, 96)
60+
scale_group.append(scale_name_1)
61+
62+
scale_name_2 = Label(FONT_1, text=SCALE_NAME_2, color=clue.CYAN)
63+
scale_name_2.anchor_point = (0.5, 0.5)
64+
scale_name_2.anchored_position = (199, 96)
65+
scale_group.append(scale_name_2)
66+
67+
# Define the zeroing button graphic
68+
zero_button_circle = Circle(14, 152, 14, fill=None, outline=clue.RED, stroke=2)
69+
scale_group.append(zero_button_circle)
70+
71+
zero_button_label = Label(FONT_1, text="Z", color=clue.RED)
72+
zero_button_label.x = 8
73+
zero_button_label.y = 150
74+
scale_group.append(zero_button_label)
75+
76+
# Place tickmark labels next to the graduated scale
77+
for i in range(-1, 6):
78+
tick_value = Label(FONT_2, text=str((MAX_GR) // 5 * i), color=clue.CYAN)
79+
if i == -1:
80+
tick_value.anchor_point = (1.0, 1.1)
81+
elif i == 5:
82+
tick_value.anchor_point = (1.0, 0.0)
83+
else:
84+
tick_value.anchor_point = (1.0, 0.5)
85+
tick_value.anchored_position = (99, 201 - (i * 40))
86+
scale_group.append(tick_value)
87+
88+
# Place the grams and ounces labels and values near the bottom of the display
89+
grams_label = Label(FONT_0, text="grams", color=clue.BLUE)
90+
grams_label.anchor_point = (1.0, 0)
91+
grams_label.anchored_position = (80, 216)
92+
scale_group.append(grams_label)
93+
94+
ounces_label = Label(FONT_0, text="ounces", color=clue.BLUE)
95+
ounces_label.anchor_point = (1.0, 0)
96+
ounces_label.anchored_position = (230, 216)
97+
scale_group.append(ounces_label)
98+
99+
grams_value = Label(FONT_0, text="0.0", color=clue.WHITE)
100+
grams_value.anchor_point = (1.0, 0.5)
101+
grams_value.anchored_position = (80, 200)
102+
scale_group.append(grams_value)
103+
104+
ounces_value = Label(FONT_0, text="0.00", color=clue.WHITE)
105+
ounces_value.anchor_point = (1.0, 0.5)
106+
ounces_value.anchored_position = (230, 200)
107+
scale_group.append(ounces_value)
108+
109+
# Define the moveable indicator bubble
110+
indicator_group = displayio.Group()
111+
bubble = Circle(120, 200, 10, fill=clue.YELLOW, outline=clue.YELLOW, stroke=3)
112+
indicator_group.append(bubble)
113+
114+
scale_group.append(indicator_group)
115+
display.show(scale_group)
116+
117+
118+
# Helpers
119+
def zero_channel():
120+
"""Prepare internal amplifier settings and zero the current channel. Use
121+
after power-up, a new channel is selected, or to adjust for measurement
122+
drift. Can be used to zero the scale with a tare weight.
123+
The nau7802.calibrate function used here does not calibrate the load cell,
124+
but sets the NAU7802 internals to prepare for measuring input signals."""
125+
nau7802.calibrate("INTERNAL")
126+
nau7802.calibrate("OFFSET")
127+
128+
129+
def read(samples=100):
130+
"""Read and average consecutive raw samples; return averaged value."""
131+
sample_sum = 0
132+
sample_count = samples
133+
while sample_count > 0:
134+
if nau7802.available:
135+
sample_sum = sample_sum + nau7802.read()
136+
sample_count -= 1
137+
return int(sample_sum / samples)
138+
139+
140+
# Activate the Sensor
141+
# Enable the internal analog circuitry, set gain, and zero
142+
nau7802.enable(True)
143+
nau7802.gain = DEFAULT_GAIN
144+
zero_channel()
145+
146+
# Play "welcome" tones
147+
clue.play_tone(1660, 0.15)
148+
clue.play_tone(1440, 0.15)
149+
150+
# The Primary Code Loop
151+
# Read sensor, move bubble, and display values
152+
while True:
153+
clue.pixel[0] = clue.GREEN # Set status indicator to green (ready)
154+
155+
# Read the raw scale value and scale for grams and ounces
156+
value = read(SAMPLE_AVG)
157+
mass_grams = round(value * CALIB_RATIO, 1)
158+
mass_ounces = round(mass_grams * 0.03527, 2)
159+
grams_value.text = f"{mass_grams:5.1f}"
160+
ounces_value.text = f"{mass_ounces:5.2f}"
161+
print(f" {mass_grams:5.1f} grams {mass_ounces:5.2f} ounces")
162+
163+
# Reposition the indicator bubble based on grams value
164+
min_gr = (MAX_GR // 5) * -1 # Minimum display value
165+
bubble.y = int(map_range(mass_grams, min_gr, MAX_GR, 240, 0)) - 10
166+
if mass_grams > MAX_GR or mass_grams < min_gr:
167+
bubble.fill = clue.RED
168+
else:
169+
bubble.fill = None
170+
171+
# Check to see if the zeroing button is pressed
172+
if clue.button_a:
173+
# Zero the sensor
174+
clue.pixel[0] = clue.RED # Set status indicator to red (stopped)
175+
bubble.fill = clue.RED # Set bubble center to red (stopped)
176+
clue.play_tone(1660, 0.3) # Play "button pressed" tone
177+
178+
zero_channel()
179+
180+
while clue.button_a:
181+
# Wait until the button is released
182+
time.sleep(0.1)
183+
184+
clue.play_tone(1440, 0.5) # Play "reset completed" tone
185+
bubble.fill = None # Set bubble center to transparent (ready)

0 commit comments

Comments
 (0)