Dizner
Dizner

Reputation: 29

Raspberry Pi 3 + temperature sensor + servo motor

I have raspberry pi 3 and trying to create smart green house model. This model should open window if temperature is too hight.

I am new writing codes in Python, found several examples: 1. for temperature sensor and 2. for servo motor to rotating.

Could anyone help me with servo motor? I would like to move servo for example to 30° if temperature is 20°C, if it is 21°C move 40° servo and so on.

I have Python code:

import sys
import Adafruit_DHT
import time
import wiringpi
sensor_args = { '11': Adafruit_DHT.DHT11,
            '22': Adafruit_DHT.DHT22,
            '2302': Adafruit_DHT.AM2302 }
if len(sys.argv) == 3 and sys.argv[1] in sensor_args:
  sensor = sensor_args[sys.argv[1]]
  pin = sys.argv[2]
else:
  print('usage: sudo ./Adafruit_DHT.py [11|22|2302] GPIOpin#')
  print('example: sudo ./Adafruit_DHT.py 2302 4 - Read from an AM2302 
  connected to GPIO #4')
  sys.exit(1)


humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)

if humidity is not None and temperature is not None:
  print('Temp={0:0.1f}*  Humidity={1:0.1f}%'.format(temperature, humidity))
else:
  print('Failed to get reading. Try again!')
  sys.exit(1)

temp=temperature
text_file = open("output.txt", "w")
text_file.write("%s" %(temp))
text_file.close()

wiringpi.wiringPiSetupGpio()
wiringpi.pinMode(18,wiringpi.GPIO.PWM_OUTPUT)
wiringpi.pwmSetMode(wiringpi.GPIO.PWM_MODE_MS)

wiringpi.pwmSetClock(192)
wiringpi.pwmSetRange(2000)
delay_period = 0.01

while temp==20.0:
  for pulse in range(50,250,1):
    wiringpi.pwmWrite(18,50)
    time.sleep(delay_period)

for pulse in range(250,50,-1):
    wiringpi.pwmWrite(18,pulse)
    time.sleep(delay_period)

Part about servo motor ir example I found on the internet. I need to replace "while" to "if". I tried by myself, but rotor all the time spin to the same angle. Can anyone help me with this little part of code?

Second question, how can I run this command in terminal "sudo python servo.py 11 17" on raspberry pi automatically in every 10 mminutes and when raspberry pi is turned on?

Thanks for your help!

Upvotes: 0

Views: 1853

Answers (1)

LeopoldVonBuschLight
LeopoldVonBuschLight

Reputation: 911

The pulse is how you are controlling the position of the servo in your code:

wiringpi.pwmWrite(18,pulse)

See this example: https://learn.adafruit.com/adafruits-raspberry-pi-lesson-8-using-a-servo-motor?view=all

Depending on your servo, a pulse value of 100 move the servo all the way left (closed in this example), and 200 all the way to the right (open in this example). You need to find these values by reading the datasheet or by experimentation. Once you have these, here is how you would set the position of the servo:

min_servo_val = 100 
max_servo_val = 200

wiringpi.pwmWrite(18, min_servo_val) # Move all the way left
time.sleep(1) # Wait a second
wiringpi.pwmWrite(18, max_servo_val) # Move all the way right

Now you can either write a function that translates temperature to a servo position between min_servo_val and max_servo_val, or use a simple if statement. Here is an example of a function to translate temp into a pulse (servo position):

def get_servo_position(temp):

    min_servo_val = 100 # Pulse value at which window is all the way closed closed
    max_servo_val = 200 # Pulse value at which window is all the way open


    full_closed_temp = 20.0 # Temperature at which window is completely closed
    full_open_temp = 26.0 # Temperature at which window is completely open

    if temp <= full_closed_temp:
        return min_servo_val
    elif temp >= full_open_temp:
        return max_servo_val
    else:
        return ((temp - full_closed_temp) / (full_open_temp - full_closed_temp)) * (max_servo_val - min_servo_val) + min_servo_val

Now you can do:

print get_servo_position(19) # 100 all the way closed

print get_servo_position(22) # 133.3, or 33% of the way between min_servo_val and max_servo_val

print get_servo_position(25) # 183.3, or 83% of the way between min_servo_val and max_servo_val

print get_servo_position(27) # 200 all the way open

Now you need a loop that checks the temperature every ten minutes and adjusts the servo position. Something like this:

while True:
    humidity, temp = Adafruit_DHT.read_retry(sensor, pin) # Get temperature.
    position = get_servo_position(temp) # Get the servo position
    wiringpi.pwmWrite(18,position) # Move to the position
    time.sleep(10*60) # Wait 10 minutes

Putting it all together, your script should look something like this:

import sys
import Adafruit_DHT
import time
import wiringpi

dht_pin = 17 # GPIO conencted to DHT
servo_pin = 18 # GPIO connected to servo

dht_sensor = Adafruit_DHT.DHT11 # Put your sensor here, or set it from command line args 


min_servo_val = 100 # Pulse value at which window is all the way closed closed
max_servo_val = 200 # Pulse value at which window is all the way open


full_closed_temp = 20.0 # Temperature at which window is completely closed
full_open_temp = 26.0 # Temperature at which window is completely open


def get_servo_position(temp):

    if temp <= full_closed_temp:
        return min_servo_val
    elif temp >= full_open_temp:
        return max_servo_val
    else:
        return ((temp - full_closed_temp) / (full_open_temp - full_closed_temp)) * (max_servo_val - min_servo_val) + min_servo_val


def main_loop():
    while True:
        humidity, temp = Adafruit_DHT.read_retry(dht_sensor, dht_pin) # Get temperature.
        position = get_servo_position(temp) # Get the servo position
        wiringpi.pwmWrite(18,position) # Move to the position
        time.sleep(10*60) # Wait 10 minutes


if __name__ == '__main__':
    # If you need to get command line arguments, do it below, otherwise just set the pins and other settings at the top of this script.

    # For example...
    # dht_pin = sys.argv[1] 
    # servo_pin = sys.argv[2]


    # Set up servo
    wiringpi.wiringPiSetupGpio()
    wiringpi.pinMode(18,wiringpi.GPIO.PWM_OUTPUT)
    wiringpi.pwmSetMode(wiringpi.GPIO.PWM_MODE_MS)

    wiringpi.pwmSetClock(192)
    wiringpi.pwmSetRange(2000)

    # Enter main loop
    main_loop()

Note that I left out command line arg parsing. If you need those you can add them right after if __name__ == '__main__':

Finally, making a script run on startup is a well covered topic: Start shell script on Raspberry Pi startup

Upvotes: 1

Related Questions