Answered step by step
Verified Expert Solution
Question
1 Approved Answer
Please rewrite this in C language (thermostat program using python) Please send screenshot of the code. Make sure it compiles and runs! + + Uses
Please rewrite this in C language (thermostat program using python) Please send screenshot of the code. Make sure it compiles and runs!
+ | ||
+ Uses a 1N4148 diode as a temperature sensor. Uses a GPIO pin and a relay | ||
+ to switch an external load when the temperature crosses a threshold set | ||
+ by a potentiometer. | ||
+""" | ||
+ | ||
+import os, collections, glob, time, atexit | ||
+ | ||
+ | ||
+# Set to True to have the relay engaged when the temperature falls below | ||
+# the set threshold: | ||
+SWITCH_WHEN_COLDER = True | ||
+ | ||
+# Or set to False to have the relay engaged when the temperature rises | ||
+# above the set threshold: | ||
+#SWITCH_WHEN_COLDER = False | ||
+ | ||
+# Used to avoid rapid switching when the temperature is right at the | ||
+# threshold. The relay will be engaged when it is this many degrees past | ||
+# the threshold, and will be disengaged once it has returned this many | ||
+# degrees past the threshold in the other direction: | ||
+HYSTERESIS = 2 # in degrees C | ||
+ | ||
+# The temperature will be sampled once every SAMPLE_INTERVAL seconds | ||
+SAMPLE_INTERVAL = 0.125 # in seconds | ||
+ | ||
+# Used to calibrate the measured temperature by offsetting it either | ||
+# positively or negatively: | ||
+TEMP_OFFSET = 0 # in degrees C | ||
+ | ||
+ | ||
+AIN_DIR = glob.glob('/sys/devices/ocp.*/thermostat-AIN.*')[0] | ||
+TEMPERATURE_FILE = '%s/AIN1' % AIN_DIR | ||
+THRESHOLD_FILE = '%s/AIN3' % AIN_DIR | ||
+ | ||
+RELAY_GPIO_NUM = '67' # GPIO2_3 = 2x32 + 3 | ||
+GPIO_BASE_DIR = '/sys/class/gpio/gpio%s' % RELAY_GPIO_NUM | ||
+ | ||
+ | ||
+def switchOff(): | ||
+ """ Disengages the relay. """ | ||
+ with open('%s/value' % GPIO_BASE_DIR, 'wb') as f: | ||
+ f.write('0') | ||
+ | ||
+ | ||
+def switchOn(): | ||
+ """ Engages the relay. """ | ||
+ with open('%s/value' % GPIO_BASE_DIR, 'wb') as f: | ||
+ f.write('1') | ||
+ | ||
+ | ||
+def relayInit(): | ||
+ """ Initializes the relay pin using the sysfs driver and ensures it is | ||
+ turned off. """ | ||
+ if not os.path.exists(GPIO_BASE_DIR): | ||
+ # The control directory for this pin doesn't exist yet, which means it | ||
+ # needs to be exported for userspace control: | ||
+ with open('/sys/class/gpio/export', 'wb') as f: | ||
+ f.write(RELAY_GPIO_NUM) | ||
+ # Give the driver time to create the interface: | ||
+ time.sleep(0.5) | ||
+ | ||
+ # Set the pin as an output: | ||
+ with open('%s/direction' % GPIO_BASE_DIR, 'wb') as f: | ||
+ f.write('out') | ||
+ # Make sure the relay is off: | ||
+ switchOff() | ||
+ | ||
+ # This ensures that the relay will be turned off when the program exits: | ||
+ atexit.register(switchOff) | ||
+ | ||
+ | ||
+def getMicroVolts(ain_file): | ||
+ """ Reads the value from the given AIN file, converts it to an integer | ||
+ and returns it. """ | ||
+ with open(ain_file, 'rb') as f: | ||
+ # Sometimes you end up trying to read the file while the kernel driver | ||
+ # is writing to it, resulting in an IOError. To prevent this from | ||
+ # crashing the program we try up to three times to read the file: | ||
+ for i in range(3): | ||
+ try: | ||
+ uv = int(f.read()) | ||
+ # We got the value without an error, return: | ||
+ return uv | ||
+ except IOError: | ||
+ continue | ||
+ # If we make it here it's failed 3 times in a row, something else is | ||
+ # probably not working. | ||
+ raise Exception('could not read %s' % ain_file) | ||
+ | ||
+ | ||
+def uvToTemp(uv): | ||
+ """ Converts a voltage in microvolts as measured on the diode, converts | ||
+ to degrees C and returns. """ | ||
+ return -0.0005625535 * uv + 410.5644360774 + TEMP_OFFSET | ||
+ | ||
+ | ||
+def getTempC(): | ||
+ """ Returns the approximate temperature of the 1N4148 diode. """ | ||
+ uv = getMicroVolts(TEMPERATURE_FILE) | ||
+ return uvToTemp(uv) | ||
+ | ||
+ | ||
+def getThreshold(): | ||
+ """ Returns the threshold temperature set by the potentiometer. """ | ||
+ uv = getMicroVolts(THRESHOLD_FILE) | ||
+ # Because the potentometer has the same range and scaling as the voltage | ||
+ # from the diode we can use the same function to convert its voltage into | ||
+ # a temperature: | ||
+ return uvToTemp(uv) | ||
+ | ||
+ | ||
+def run(): | ||
+ """ Runs the thermostat program until ctrl-c is pressed. """ | ||
+ relayInit() | ||
+ engaged = False # Keep track of relay state for printing | ||
+ try: | ||
+ while(True): | ||
+ temp = getTempC() | ||
+ thresh = getThreshold() | ||
+ | ||
+ # The thermostat logic: | ||
+ if temp >= thresh + HYSTERESIS: | ||
+ if SWITCH_WHEN_COLDER: switchOff() | ||
+ else: switchOn() | ||
+ elif temp <= thresh - HYSTERESIS: | ||
+ if SWITCH_WHEN_COLDER: switchOn() | ||
+ else: switchOff() | ||
+ | ||
+ # Log the values to the terminal: | ||
+ if engaged: | ||
+ print "temp=%i C - thresh=%i C - relay engaged" % (temp, thresh) | ||
+ else: | ||
+ print "temp=%i C - thresh=%i C - relay disengaged" % (temp, thresh) | ||
+ | ||
+ # Wait the set interval: | ||
+ time.sleep(SAMPLE_INTERVAL) | ||
+ | ||
+ except KeyboardInterrupt: | ||
+ print "Exiting" | ||
+ exit(0) | ||
+ | ||
+ | ||
+if __name__ == '__main__': | ||
+ run() |
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started