Python Forum
Normalizing a value from HX711
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Normalizing a value from HX711
#1
I have a scale project that is used to determine the quantity of beer in a keg. Since not all beers weigh the same, the full weight of the keg is inconsistent. I'd like to find a way to "normalize" the range of variables used for the varied weights. When I run the following code, it starts out with getting a "zero" reference then I place the full keg on. With a full keg, I get values between 500000 and 515000. How do I convert the larger number to a simple "100" so that I could use percentage of range (0-100) instead of 0-inconsistent number.

# Scale project that uses a scale to determine the volume of beer in the keg.
# A row of LEDs indicates the state of the program and the volume of the keg.
# A requests post initiates a push notification to my phone when the weight of the keg changes.

import time
import sys
import requests
from gpiozero import LED


#Define LED indicators - these are GPIO numbers
LED1 = LED(21) #Blue
LED2 = LED(26) #Red
LED3 = LED(20) #Amber
LED4 = LED(19) #Green
LED5 = LED(16) #Green
LED6 = LED(13) #Green
LED7 = LED(6) #Green
LED8 = LED(12) #Green
LED9 = LED(5) #Pink

EMULATE_HX711=False

referenceUnit = 1

if not EMULATE_HX711:
    import RPi.GPIO as GPIO
    from hx711 import HX711
else:
    from emulated_hx711 import HX711

def moving_average(prev_average, new_value, num_steps = 5.0):
   return (prev_average * (num_steps - 1) + new_value) / num_steps

average = weight = 400000  #just a value close to what a newly deployed keg would be
w_threshold = 2000  #approximate value of 3-4 fluid ounces of the beer 

def cleanandexit():
    print("Cleaning...")
    if not EMULATE_HX711:
        GPIO.cleanup()        
    print("Bye!")
    sys.exit()

hx = HX711(27, 22)
hx.set_reading_format("MSB", "MSB")
hx.set_reference_unit(1)
hx.reset()
hx.tare()

print("The scale is ready")  
print("put the keg on...")

LED9.blink(.2,3)  # indication that the scale is running - not blinking means program crash
start = time.time()

while True:
    try:        
        keg1 = hx.get_weight(5)
        weight = keg1
        keg1 = round(keg1,3)
        start_weight = keg1
        print(keg1, average)
        if time.time() - start > 5:
            weight = keg1
            lost_weight = average - keg1
            lost_weight = round(lost_weight,3)
            if lost_weight > w_threshold:
               #r = requests.post("https://bit.ly/editedforprivacy")  #Join URL that triggers push notification to my phone
               print("You got served")
               average = keg1  #resets average to new keg1 value for faster recovery
            print(lost_weight)  #visual indication of how much was poured - one pint is about 8400
            average = moving_average(average, weight)
            average = round(average,3)
            start = time.time()


        if 8000 >= keg1 <= 507001: #keg is outside of usable range - flashes when keg is missing (indicating tare is complete at startup)
            LED1.blink(.2,.2)
        else:
            LED1.off()

        if 109800 >= keg1 >= 80000: #Red less than 5% - DANGER
            LED2.blink(.5,.5)
        else:
            LED2.off()
            
        if 130600 >= keg1 >= 109799: #Amber less than 10% - Warning
            LED3.on()
        else:
            LED3.off()
            
        if 507000 >= keg1 >= 130599: #  Green 10-20% - Caution
            LED4.on()
        else:
            LED4.off()
            
        if 507000 >= keg1 >= 172199: #Green2 20-40%
            LED5.on()
        else:
            LED5.off()
            
        if 507000 >= keg1 >= 255400: #Green3 40-60%
            LED6.on()
        else:
            LED6.off()
            
        if 507000 >= keg1 >= 338600: #Green4 60-80%
            LED7.on()
        else:
            LED7.off()
            
        if 507000 >= keg1 >= 421800: #Green5 80-100%
            LED8.on()
        else:
            LED8.off()


        hx.power_down()
        hx.power_up()
        time.sleep(1)


    except (KeyboardInterrupt, SystemExit):

        cleanandexit()
Keep in mind that this code's values are based on a full keg being about 507000 and an empty keg being about 89000. This works out to a net weight of about 418000, which is the weight of the beer.

I have found that I can get inconsistent "full" values using the same keg. Running this 4 times this morning, I got the following values for full: 507000, 511000, 509000, and 516000.
Reply
#2
scale = 100 / (full - empty)
percent_full = (weight - empty) * scale

Empty is the weight of an empty keg. Hopefully this is consistent enough to be a constant. full is the weight of a full keg and would be taken just before entering the loop. It will be different for each keg.
Reply
#3
That seems easy enough. So what I need to do now is to tell the program when to capture the "full" value. Plobby do that with a button push, kind of like a reset function. I will see what I can do with this. Thanks for the idea.
Reply
#4
So I added a few things, haven't been able to test it yet. Let me know if this is what you were talking about. I only changed the part where these maths control the lights, not much else. I also added the reset button on GPIO4, expecting a push of that button will reset the "full" value to the currently observed "keg1" value that the HX711 is reporting. On paper, this looks like what I am after.

Behold the code:
# Scale project that uses a scale to determine the volume of beer in the keg.
# A row of LEDs indicates the state of the program and the volume of the keg.
# A requests post initiates a push notification to my phone when the weight of the keg changes.
 
import time
import sys
import requests
from gpiozero import LED
 
 
#Define LED indicators - these are GPIO numbers
LED1 = LED(21) #Blue
LED2 = LED(26) #Red
LED3 = LED(20) #Amber
LED4 = LED(19) #Green
LED5 = LED(16) #Green
LED6 = LED(13) #Green
LED7 = LED(6) #Green
LED8 = LED(12) #Green
LED9 = LED(5) #Pink
Reset = Button(4) #Button to reset the variable "full" to the current scale value


EMULATE_HX711=False
 
referenceUnit = 1
 
if not EMULATE_HX711:
    import RPi.GPIO as GPIO
    from hx711 import HX711
else:
    from emulated_hx711 import HX711
 
def moving_average(prev_average, new_value, num_steps = 5.0):
   return (prev_average * (num_steps - 1) + new_value) / num_steps

def reset_full():
    full = keg1
    
average = weight = 400000  #just a value close to what a newly deployed keg would be
w_threshold = 2000  #approximate value of 3-4 fluid ounces of the beer 
 
def cleanandexit():
    print("Cleaning...")
    if not EMULATE_HX711:
        GPIO.cleanup()        
    print("Bye!")
    sys.exit()
 
hx = HX711(27, 22)
hx.set_reading_format("MSB", "MSB")
hx.set_reference_unit(1)
hx.reset()
hx.tare()
 
print("The scale is ready")  
print("put the keg on...")
 
LED9.blink(.2,3)  # indication that the scale is running - not blinking means program crash
start = time.time()
 
while True:
    try:        
        keg1 = hx.get_weight(5)
        weight = keg1
        keg1 = round(keg1,3)
        start_weight = keg1
        
        print(keg1, average)
        if time.time() - start > 5:
            weight = keg1
            lost_weight = average - keg1
            lost_weight = round(lost_weight,3)
            if lost_weight > w_threshold:
               #r = requests.post("https://bit.ly/editedforprivacy")  #Join URL that triggers push notification to my phone
               print("You got served")
               average = keg1  #resets average to new keg1 value for faster recovery
            print(lost_weight)  #visual indication of how much was poured - one pint is about 8400
            average = moving_average(average, weight)
            average = round(average,3)
            start = time.time()
            Reset.when_pressed = reset_full

            full = keg1
            empty = 89000
            scale = 100 / (full - empty)
            percent_full = (weight - empty) * scale

 
        if 1 >= percent_full <= 102: #keg is outside of usable range - flashes when keg is missing (indicating tare is complete at startup)
            LED1.blink(.2,.2)
        else:
            LED1.off()
 
        if 1.1 >= percent_full >= 5: #Red less than 5% - DANGER
            LED2.blink(.5,.5)
        else:
            LED2.off()
             
        if 100 >= percent_full >= 10: #Amber less than 10% - Warning
            LED3.on()
        else:
            LED3.off()
             
        if 100 >= percent_full >= 20: #  Green 10-20% - Caution
            LED4.on()
        else:
            LED4.off()
             
        if 100 >= percent_full >= 40: #Green2 20-40%
            LED5.on()
        else:
            LED5.off()
             
        if 100 >= percent_full >= 60: #Green3 40-60%
            LED6.on()
        else:
            LED6.off()
             
        if 100 >= percent_full >= 80: #Green4 60-80%
            LED7.on()
        else:
            LED7.off()
             
        if 100 >= keg1 >= 80.1: #Green5 80-100%
            LED8.on()
        else:
            LED8.off()
 
 
        hx.power_down()
        hx.power_up()
        time.sleep(1)
 
 
    except (KeyboardInterrupt, SystemExit):
 
        cleanandexit()
Reply
#5
The percent_full equation converts the keg weight to a number in the range 0 to 100. This is the number you should use for calculating average and turning LED's on and off. It should be calculated each time you weigh the keg.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Issue with HX711 reading duckredbeard 0 2,179 Aug-28-2020, 10:00 AM
Last Post: duckredbeard
  HX711&matplotlib problems olego 0 1,932 Jul-12-2019, 12:22 PM
Last Post: olego
  Guizero HX711 Load Cell and python3 stdout? Tesla 1 3,733 Jan-16-2019, 01:15 PM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020