0

Greetings fellow python programmers. I am building a raspberry pi project that is designed to use moisture sensors in my garden. I have the program designed to take readings for thirty seconds and then average them all into one number. It uses four sensors and runs off of python3.5 The sensors all work just fine, but I'm having a problem getting python to do the math to average the inputs. I think it is adding the variables, but it doesn't seem to be dividing them. Here is the code:


        TEST_SOIL()
        outpuT = str(output)
        print("Moisture:", outpuT)
        GPIO.output(buzzer,GPIO.HIGH)
        sleep(0.1) # Delay in seconds
        GPIO.output(buzzer,GPIO.LOW)
        sleep(0.1)
        GPIO.output(buzzer,GPIO.HIGH)
        sleep(0.1) # Delay in seconds
        GPIO.output(buzzer,GPIO.LOW)
        print("TESTING SOIL")
        o1 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o2 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o3 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o4 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o5 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o6 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o7 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o8 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o9 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o10 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o11 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o12 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o13 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o14 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o15 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o16 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o17 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o18 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o19 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o20 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o21 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o22 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o23 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o24 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o25 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o26 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o27 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o28 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o29 = (output + output2 + output3 + output4/4)
        sleep(1)
        TEST_SOIL()
        o30 = (output + output2 + output3 + output4/4)
        sleep(1)
        o = (o1 + o2 + o3 + o4 + o5 + o6 + o7 + o8 + o9 + o10 + o11 + o12 + o13 + o14 + o15 + o16 + o17 + o18 + o19 + o20 + o21 + o22 + o23 + o24 + o25 + o26 + o27 + o28 + o29 + o30)
        o = (o/30) 

If anyone is wondering what "TEST_SOIL()" is, that is my own function I created earlier in the program. It is defined here:

def TEST_SOIL():
   output = analogInput(0) # Reading from CH0
   output = interp(output, [0, 1023], [100, 0])
   output = int(output)
   output = (output - 12.5)
   output2 = analogInput(1) # Reading from CH0
   output2 = interp(output2, [1, 1023], [100, 1])
   output2 = int(output2)
   output2 = (output2 - 12.5)
   output3 = analogInput(2) # Reading from CH0
   output3 = interp(output3, [2, 1023], [100, 2])
   output3 = int(output3)
   output3 = (output3 - 12.5)
   output4 = analogInput(3) # Reading from CH0
   output4 = interp(output4, [3, 1023], [100, 3])
   output4 = int(output4)
   output4 = (output4 - 12.5)

I need to metion that this code also controls a small buzzer to clear up any confusion with the "GPIO.output(buzzer,high/low)" text. If anyone can tell me how to fix this code that would be great.
:)

UNKNOWN
  • 105
  • 10

3 Answers3

3

I took the liberty of refactoring your code a bit.

I assume the 4 different analog reads need to be as such and didn't touch them, but otherwise...

  • test_soil now returns a 4-tuple of the readings.
  • average_output() takes any iterable of numbers to average over.
  • beep() beeps the buzzer.
  • main calls the above bits in a loop, gathering values into an array, which it then finally averages.
def TEST_SOIL():
    output = analogInput(0)  # Reading from CH0
    output = interp(output, [0, 1023], [100, 0])
    output = int(output)
    output = output - 12.5
    output2 = analogInput(1)  # Reading from CH0
    output2 = interp(output2, [1, 1023], [100, 1])
    output2 = int(output2)
    output2 = output2 - 12.5
    output3 = analogInput(2)  # Reading from CH0
    output3 = interp(output3, [2, 1023], [100, 2])
    output3 = int(output3)
    output3 = output3 - 12.5
    output4 = analogInput(3)  # Reading from CH0
    output4 = interp(output4, [3, 1023], [100, 3])
    output4 = int(output4)
    output4 = output4 - 12.5
    return (output, output2, output3, output4)


def average_output(o):
    return sum(o) / len(o)


def beep():
    GPIO.output(buzzer, GPIO.HIGH)
    sleep(0.1)  # Delay in seconds
    GPIO.output(buzzer, GPIO.LOW)


def main():
    ao = average_output(TEST_SOIL())
    print("Initial Moisture:", ao)
    beep()
    beep()
    print("TESTING SOIL")
    values = []
    for x in range(30):
        values.append(average_output(TEST_SOIL()))
        sleep(1)
    final_average = average_output(values)
    print("Final Moisture:", final_average )
AKX
  • 152,115
  • 15
  • 115
  • 172
  • It seems to be working. One last thing, will telling main to "return final_average " put out a variable I can work with to record the data? – UNKNOWN May 17 '20 at 15:43
  • I tried it out, but when I said "main() o = final_average" python said that final_average was not defined . – UNKNOWN May 22 '20 at 22:13
  • I also noticed something strange: The code always puts out the number "20.5" even if I adjust the sensors. Can you tell me if the code is doing this, or the sensors? – UNKNOWN May 22 '20 at 23:51
2

change (output + output2 + output3 + output4/4) to (output + output2 + output3 + output4)/4

Your code first divides by four the last variable (ouotput4) and then adding them together.

(Edit: forgot there is no average function for list. sorry. You can use sum() for some list and then divide it by len() of this list)

Roim
  • 2,986
  • 2
  • 10
  • 25
1

this might be able to fix ur code and tidy it a bit instead of writing the same thing again u can use a for loop to make the job easier

for step in range(30):
    TEST_SOIL()
    op_avg = (output1 + output2 + output3 + output4) / 4.0
    op = op + op_avg
    sleep(1)
op = op/30

hope it helps

Mehul
  • 115
  • 6