|
Post by raspipeter on Mar 27, 2014 13:33:10 GMT -8
Hi,
We have some interesting codes already found on this support forum about this topic, but still not what I'm looking for. I would like to use a script that does NOT specify the individual unique ID's of the temperature sensors and that is a bit flexible in the number of sensors that you want to use. I found the approach from "grandad" Martin in the Thread "Paid my $$, installed; now what?" on page 3 a real good start, but so far, I also could not get it to work. I'm thinking about using about 50 sensors simultaneously, but thought it can be made easier than writing the code for each individual sensor 50 times. I would be awsome to get it working in a way like used in the "curacao project" with nice trend plots and some statistics available. Has anyone already successful implemented multiple temperature sensors in a working "Local.py" file that you want to share? Looking forward for input on this.
Thanks in advance, Peter
|
|
|
Post by SDL on Mar 28, 2014 14:17:54 GMT -8
Hi Peter,
Post your code for one sensor and I'll turn it into a function for you. I agree about the trend plots.
I just got an email from Faraday (of Project Curacao) and he is working on his next project, "Mouse Air", a cat toy launcher based on the cat's RFID tag. He's got the mock up working (with the control panel on RasPiConnect) and will finish the mechanicals this weekend. This guy is a lunatic! But fun.
He's thinking he overdid the motors and it will throw the mouse 20 feet. Film at 11.
BP
|
|
|
Post by raspipeter on Mar 29, 2014 15:27:31 GMT -8
Hi BP, This is the working code for a single sensor. import os
import glob
import time
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '10*')[0]
device_file = device_folder + '/w1_slave'
def read_temp_raw():
f = open(device_file, 'r')
lines = f.readlines()
f.close()
return lines
def read_temp():
lines = read_temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
return temp_c
while True:
print(read_temp())
time.sleep(5)
Changing in the line "device_folder = glob.glob(base_dir + '10*')[0] " the index [0] to a [1], or [2] etc. will give me nicely the reading every 5 seconds of the second sensor,third sensor etc. But how to nicely reduce the size of the code when using around 50 sensors? Looking forward to learn something about this. Regards, Peter
|
|
|
Post by SDL on Mar 30, 2014 11:26:48 GMT -8
raspipeter,
Parameterize the device address like below:
import os import glob import time
os.system('modprobe w1-gpio') os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'
def read_temp_raw():
f = open(device_file, 'r') lines = f.readlines() f.close() return lines
def read_temp(device_file):
lines = read_temp_raw(device_file)
while lines[0].strip()[-3:] != 'YES': time.sleep(0.2) lines = read_temp_raw(device_file)
equals_pos = lines[1].find('t=')
if equals_pos != -1: temp_string = lines[1][equals_pos+2:] temp_c = float(temp_string) / 1000.0 return temp_c
while True: i = 0 maxcount =len(glob.glob(base_dir + '10*')) while i < maxcount: device_folder = glob.glob(base_dir + '10*')[i] print "device_folder=", device_folder device_file = device_folder + '/w1_slave' print(read_temp(device_file)) time.sleep(5) i=i+1
print "done with reads" time.sleep(5)
Hope that helps!
BP
|
|
|
Post by raspipeter on Mar 31, 2014 13:26:40 GMT -8
Hi BP, Well thank you very much for sharing this example how to hook up multiple sensors! There was a small typing error I guess, because I had to change the following: "def read_temp_raw (): " had to be changed to "def read_temp_raw (device_file): " def read_temp_raw(device_file):
f = open(device_file, 'r')
lines = f.readlines()
f.close()
return lines But this works like perfectly. The only remaining thing is to add this code into the Local.py file in order to read the individual sensors on the iPad / iPhone. I think it should be something like this, but since I have some network problems now, I could not check it out in "real life" :-) #!/usr/bin/python # Filename: Local.py # MiloCreek JS MiloCreek # Version 2.8 8/12/13 # # Local Execute Objects for RasPiConnect # to add Execute objects, modify this file # # # # RasPiConnectServer interface constants
REMOTE_WEBVIEW_UITYPE = 1 ACTION_BUTTON_UITYPE = 16 FEEDBACK_ACTION_BUTTON_UITYPE = 17 SINGLE_LED_DISPLAY_UITYPE = 32 SPEEDOMETER_UITYPE = 64 VOLTMETER_UITYPE = 128 BARMETER_UITYPE = 129 SERVER_STATUS_UITYPE = 256 PICTURE_REMOTE_WEBVIEW_UITYPE = 512 LABEL_UITYPE = 1024 FM_BLINK_LED_UITYPE = 2048 TEXT_DISPLAY_UITYPE = 4096 TOGGLE_SWITCH_UITYPE = 33 SEND_TEXT_UITYPE = 34
# system imports import sys import subprocess
# RasPiConnectImports
import Config import Validate import BuildResponse import os import glob import time
def ExecuteUserObjects(objectType, element):
# Example Objects
# fetch information from XML for use in user elements
#objectServerID is the RasPiConnect ID from the RasPiConnect App
objectServerID = element.find("./OBJECTSERVERID").text objectID = element.find("./OBJECTID").text
if (Config.debug()): print("objectServerID = %s" % objectServerID) # # check to see if this is a Validate request # validate = Validate.checkForValidate(element)
if (Config.debug()): print "VALIDATE=%s" % validate
# Build the header for the response
outgoingXMLData = BuildResponse.buildHeader(element)
# objects are split up by object types by Interface Constants # # # # search for matches to object Type
# object Type match if (objectType == VOLTMETER_UITYPE):
if (Config.debug()): print "VOLTMETER_UITYPE of %s found" % objectServerID
#check for validate request if (validate == "YES"): outgoingXMLData += Validate.buildValidateResponse("YES") outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData
# normal response requested os.system('modprobe w1-gpio') os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'
def read_temp_raw(device_file): f = open(device_file, 'r') lines = f.readlines() f.close() return lines
def read_temp(device_file): lines = read_temp_raw(device_file) while lines[0].strip()[-3:] != 'YES': time.sleep(0.2) lines = read_temp_raw(device_file) equals_pos = lines[1].find('t=') if equals_pos != -1: temp_string = lines[1][equals_pos+2:] temp_c = float(temp_string) / 1000.0 return temp_c #**************************************************************************************** #M-0 is the DS18B20 temperature if (objectServerID == "M-0"): i = 0 maxcount = len(glob.glob(base_dir + '10*')) while i < maxcount: device_folder = glob.glob(base_dir +'10*')[i] device_file = device_folder + '/w1_slave' responseData = "%3.2f" % temp_c outgoingXMLData += BuildResponse.buildResponse(responseData) outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData #**************************************************************************************** #M-1 is the DS18B20 temperature if (objectServerID == "M-1"): i = 1 maxcount = len(glob.glob(base_dir + '10*')) while i < maxcount: device_folder = glob.glob(base_dir +'10*')[i] device_file = device_folder + '/w1_slave' responseData = "%3.2f" % temp_c outgoingXMLData += BuildResponse.buildResponse(responseData) outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData #**************************************************************************************** #M-2 is the DS18B20 temperature if (objectServerID == "M-2"): i = 2 maxcount = len(glob.glob(base_dir + '10*')) while i < maxcount: device_folder = glob.glob(base_dir +'10*')[i] device_file = device_folder + '/w1_slave' responseData = "%3.2f" % temp_c outgoingXMLData += BuildResponse.buildResponse(responseData) outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData #**************************************************************************************** # etc. for as many sensors as you want to read out with a "VOLTMETER_UITYPE" # like M-0, M-1, M-2, etc. # #**************************************************************************************** else: return "" # returning a zero length string tells the server that you have not matched # the object and server return ""
A copy of this file below: Local.py (3.75 KB) Thanks in advance for your comments on the Local.py file above (that I could not test so far...). Regards, Peter
|
|
|
Post by SDL on Mar 31, 2014 18:30:36 GMT -8
Hi Peter,
I'm not sure what you are trying to do. Are you trying to read ONE temperature with each meter?
Here's what you have:
#**************************************************************************************** #M-0 is the DS18B20 temperature if (objectServerID == "M-0"): i = 0 maxcount = len(glob.glob(base_dir + '10*')) while i < maxcount: device_folder = glob.glob(base_dir +'10*')[i] device_file = device_folder + '/w1_slave' responseData = "%3.2f" % temp_c outgoingXMLData += BuildResponse.buildResponse(responseData) outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData
If you are trying to read ONE temperature per meter, then it seems to me that you should have:
#**************************************************************************************** #M-0 is the DS18B20 temperature if (objectServerID == "M-0"): device_folder = glob.glob(base_dir +'10*')[0] device_file = device_folder + '/w1_slave' temp_c = read_temp(device_file) responseData = "%3.2f" % temp_c outgoingXMLData += BuildResponse.buildResponse(responseData) outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData
Best regards,
BP
|
|
|
Post by raspipeter on Apr 1, 2014 13:33:00 GMT -8
Hi BP,
Thanks a lot, exactly what I was looking for. I wanted to use for each sensor a Voltmeter object to display the temperature and with your code I succeeded to get this to work.
One thing I was wondering about was that it was not indicating to me that the object was "valid" in the Edit Control screen. I noticed that I forgot to add that part of the code. So now for every sensor I used the following code and it works perfectly.
#M-0 is the DS18B20 temperature if (objectServerID == "M-0"): #check for validate request if (validate == "YES"): outgoingXMLData += Validate.buildValidateResponse("YES") outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData device_folder = glob.glob(base_dir +'10*')[0] device_file = device_folder + '/w1_slave' temp_c = read_temp(device_file) responseData = "%3.2f" % temp_c outgoingXMLData += BuildResponse.buildResponse(responseData) outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData
Thanks again BP for this great input. My next project would be to get the nice trend-plot like used in the Curacao project.
Peter
|
|
|
Post by SDL on Apr 1, 2014 15:33:23 GMT -8
|
|
|
Post by raspipeter on May 21, 2014 13:12:15 GMT -8
Just for those that want to use more than 10 DS18B20 temperature sensors, it is good to be aware of the "default" limitation of "10" temperature sensors with the 1-wire code as used in the example before. This limit of "10" is set in the code of the module "wire".
When looking for solutions to get more than 10 sensors hooked up, I came in contact with the person that wrote the code for the DS18B20 driver. He informed me that the limit can be changed relatively easily (in my example towards "50") when you simply add the following line to the script you are using (or in my example into the Local.py file):
modprobe wire max_slave_count=50
#************************************************************************************** if (objectType == VOLTMETER_UITYPE):
if (Config.debug()): print "VOLTMETER_UITYPE of %s found" % objectServerID
# normal response requested
os.system('modprobe wire max_slave_count=50') os.system('modprobe w1-gpio') os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'
def read_temp_raw(device_file): f = open(device_file, 'r') lines = f.readlines() f.close() return lines
def read_temp(device_file): lines = read_temp_raw(device_file) while lines[0].strip()[-3:] != 'YES': time.sleep(0.2) lines = read_temp_raw(device_file) equals_pos = lines[1].find('t=') if equals_pos != -1: temp_string = lines[1][equals_pos+2:] temp_c = float(temp_string) / 1000.0 return temp_c
#********************************************************************************************** #M-0 is the DS18B20 temperature if (objectServerID == "M-0"):
#check for validate request if (validate == "YES"): outgoingXMLData += Validate.buildValidateResponse("YES") outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData device_folder = glob.glob(base_dir +'28*')[0] device_file = device_folder + '/w1_slave' temp_c = read_temp(device_file) responseData = "%3.1f" % temp_c outgoingXMLData += BuildResponse.buildResponse(responseData) outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData
#M-1 is the DS18B20 temperature if (objectServerID == "M-1"): #check for validate request if (validate == "YES"): outgoingXMLData += Validate.buildValidateResponse("YES") outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData
device_folder = glob.glob(base_dir +'28*')[1] device_file = device_folder + '/w1_slave' temp_c = read_temp(device_file) responseData = "%3.1f" % temp_c outgoingXMLData += BuildResponse.buildResponse(responseData) outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData
#M-2 is the DS18B20 temperature if (objectServerID == "M-2"): #check for validate request if (validate == "YES"): outgoingXMLData += Validate.buildValidateResponse("YES") outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData
device_folder = glob.glob(base_dir +'28*')[2] device_file = device_folder + '/w1_slave' temp_c = read_temp(device_file) responseData = "%3.1f" % temp_c outgoingXMLData += BuildResponse.buildResponse(responseData) outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData
#M-3 is the DS18B20 temperature #repeat the entire block like M-1, M-2 etc for as many sensors as required!
One thing that I noticed is that when using for instance 12 "Voltmeter" Control Types on one single page in the RasPiConnectServer app on the iPad, I frequently got "0" readings on all 12 channels. If this has been split up over 2 pages (2 x 6 Voltmeter Control types) I have no problems. So far I don't know why this is appearing like that.
Hope this will be of help for all.
Regards, Peter
|
|