Page 1 of 1

Ultrasonic Sensor

Posted: Wednesday 10 June 2015 12:14
by njensen
Hi all.
Have this HC-SR04 sensor connected to my RPI. Script is working.
Is there a simple way to get a python script value implemented into domoticz, i guess as a virtual sensor?
Been searching the forum but can't find a simple solution, i'm a newbie.
I hope you can help me.

-Nick

Re: Ultrasonic Sensor

Posted: Wednesday 10 June 2015 14:23
by thegritche
Yes you just need to create a virtual device with the type "Distance"

Then in the device tab , use the green arrow to name it and write down the idx number

After that you need to use the JSON API to fill your datas in the widget with your preferred language (python,shell, php...)

Some details about the API about distance sensors here
https://www.domoticz.com/wiki/Domoticz_ ... nce_Sensor

I try , it works !

Re: Ultrasonic Sensor

Posted: Friday 12 June 2015 8:47
by njensen
Thanks for the quick reply!

I tried with a example code from another post where you 'login' via JSON and display a given value.
Like this

url = 'http://192.168.0.33:8080/json.htm?type= ... value=24.5'

It works great! The distance sensor shows 24.5cm
In my python script, when i print the value 'distance' it displays ex. 40cm
When i add the json stuff to my script and change svalue=24.5 to svalue=distance the dummy sensor displays 0.
It's probably not that simple, or is it? :?

Re: Ultrasonic Sensor

Posted: Friday 12 June 2015 9:22
by njensen
Got it working

Changed the svalue to svalue='+str(distance)

Re: Ultrasonic Sensor

Posted: Friday 12 June 2015 11:11
by ThinkPad
Please share your script here, can be useful for others (and to have a 'backup' yourself hehe)

Re: Ultrasonic Sensor

Posted: Wednesday 17 June 2015 8:52
by njensen
Sure thing.
I have turned the value around. So when the distance is greater the value is lower. ex. 20cm = 800 liters, 80cm = 200 liters. I have a 1000 liters water tank filled with rainwater and used for watering. I just wish i could change the cm/inch to Liters. Maybe someone can help?

Code: Select all

import time
import RPi.GPIO as GPIO
import urllib2
import urllib
import json

def log_waterlevel(distance):
    
    conn=sqlite3.connect("distance.db")
    curs=conn.cursor()

    curs.execute("INSERT INTO volume values(datetime('now'), (?))", (distance,))

    #commit the changes
    conn.commit()
    conn.close()
    
def measure():
  # This function measures a distance

  GPIO.output(GPIO_TRIGGER, True)
  time.sleep(0.00001)
  GPIO.output(GPIO_TRIGGER, False)
  start = time.time()
  
  while GPIO.input(GPIO_ECHO)==0:
    start = time.time()

  while GPIO.input(GPIO_ECHO)==1:
    stop = time.time()

  elapsed = stop-start
  distance = 1000-(elapsed * 34300)/2*10
  return distance

def measure_average():
  # This function takes 3 measurements and
  # returns the average.

  distance1=measure()
  time.sleep(0.1)
  distance2=measure()
  time.sleep(0.1)
  distance3=measure()
  distance = distance1 + distance2 + distance3
  distance = distance / 3
  round(distance,0)
  return distance

# -----------------------
# Main Script
# -----------------------

# Use BCM GPIO references
# instead of physical pin numbers
GPIO.setmode(GPIO.BCM)

# Define GPIO to use on Pi
GPIO_TRIGGER = 24
GPIO_ECHO    = 23

print "Ultrasonic Measurement"

# Set pins as output and input
GPIO.setup(GPIO_TRIGGER,GPIO.OUT)  # Trigger
GPIO.setup(GPIO_ECHO,GPIO.IN)      # Echo

# Set trigger to False (Low)
GPIO.output(GPIO_TRIGGER, False)

# Wrap main content in a try block so we can
# catch the user pressing CTRL-C and run the
# GPIO cleanup function. This will also prevent
# the user seeing lots of unnecessary error
# messages.
distance = measure_average()
if distance > 0:

url = 'http://192.168.0.33:8080/json.htm?type=command&param=udevice&idx=15&nvalue=0&svalue='+str(round(distance,-1))
username = '<USERNAME>'
password = '<PASSWORD>'
p = urllib2.HTTPPasswordMgrWithDefaultRealm()
p.add_password(None, url, username, password)
handler = urllib2.HTTPBasicAuthHandler(p)
opener = urllib2.build_opener(handler)
urllib2.install_opener(opener)

page = urllib2.urlopen(url).read()

print distance
print page
else: print"Not working"    

GPIO.cleanup()


Re: Ultrasonic Sensor

Posted: Sunday 12 July 2015 23:37
by kivster
I'm working on something similar to you, but for my oil tank. You've got the distance from the top of your tank to the water, so you're half way there. It's not too difficult to turn this into something more useful, but the shape of your tank will play a part in this.

What you have right now is effectively the 'air space' in your tank calculated by measure(). If you know the height of your tank you can subtract the 'air space' from the height of your tank to get the height of the water in the tank. For example:

Code: Select all

# Might as well set everything we know about the tank here
tank_height = 50
tank_length = 200
tank_width = 100
tank_capacity = 1000

def get_water_height():
    # Returns how high the water is in the tank
    air_space = measure()
    water_level = tank_height - air_space
    print "Water level is ", water_level, " cm"
    return water_level
Now you have the height of the water in the tank. If you just care about (very) approximate measurements and your tank is a fairly cuboidal shape, you could do something quick and dirty like this:

Code: Select all

water_litres_remaining = tank_capacity * (water_level / tank_height)
print "There is {} litres of water in the tank".format(water_litres_remaining)
[/code]

Or even get a rough percentage:

Code: Select all

percent_full = (oil_level / oil_tank_height) * 100
print "Oil tank is {}% full".format(percent_full)
If you wanted to do some proper maths to calculate the litres of water remaining, you need to factor in the shape of your tank.

Let me know what shape tank do you have and I'll see what I can come up with.

Hope this helps.

Re: Ultrasonic Sensor

Posted: Friday 11 December 2015 19:22
by dwmw2
It would be good to have a generic solution to this, to turn a distance reading (and configured tank dimensions) into a volume in litres; perhaps with the latter being adjusted for liquid expansion with temperature (so the expansion coefficient would want to be configured too).

I've got support in rtl_433 now for various brands of ultrasonic oil tank monitor which all seem to use the same protocol. We get a distance measurement and (since it needs it to calibrate for the speed of sound which varies) temperature. Which is fairly much what we get from a lot of home-created solutions too. So perhaps we should add that as a distinct 'ilquid tank' type of device?

Re: Ultrasonic Sensor

Posted: Saturday 12 December 2015 0:32
by dwmw2
I threw together a script to turn a depth (of air) reading into percentage and volume (in litres):
http://www.domoticz.com/wiki/Lua_-_Oil_Tank_Monitor

Feedback welcome!

Re: Ultrasonic Sensor

Posted: Friday 08 January 2016 17:40
by blackdog65
@dwmw2

Hiya, I've been reading/following with interest your many posts here (and other forums!) ref. watchman/apollo and rtl_433. I have the apollo visual (same as ultrasonic but has lcd on sensor too) and I'm currently trying to get some form of intelligible signal from it via rtl_433. :geek:

If I enter "rtl_433 -a -R 42 and touch a magnet to the apollo I get

Code: Select all

*** signal_start = 2249224, signal_end = 2280690
signal_len = 31466,  pulses = 1
Distance coding: Pulse length 11465

Short distance: 1000000, long distance: 0, packet distance: 0

p_limit: 11465
bitbuffer:: Number of rows: 0
streamed until I touch it again.

If left scanning I get

Code: Select all

*** signal_start = 32841209, signal_end = 32879765
signal_len = 38556,  pulses = 64
Iteration 1. t: 182    min: 121 (52)    max: 244 (12)    delta 5
Iteration 2. t: 182    min: 121 (52)    max: 244 (12)    delta 0
Pulse coding: Short pulse length 121 - Long pulse length 244

Short distance: 121, long distance: 0, packet distance: 147

p_limit: 182
bitbuffer:: Number of rows: 25
[00] {1} 00 : 0
[01] {1} 00 : 0
[02] {1} 00 : 0
[03] {1} 00 : 0
[04] {1} 00 : 0
[05] {1} 00 : 0
[06] {1} 00 : 0
[07] {1} 00 : 0
[08] {1} 00 : 0
[09] {1} 00 : 0
[10] {1} 00 : 0
[11] {1} 00 : 0
[12] {1} 00 : 0
[13] {1} 00 : 0
[14] {1} 00 : 0
[15] {1} 00 : 0
[16] {1} 00 : 0
[17] {1} 00 : 0
[18] {1} 00 : 0
[19] {1} 00 : 0
[20] {1} 00 : 0
[21] {1} 00 : 0
[22] {1} 00 : 0
[23] {1} 00 : 0
[24] {40} 91 6c 1b 00 40 : 10010001 01101100 00011011 00000000 01000000
Which doesn't make any more sense to me.

Any chance of a pointer as to where I'm going wrong? :D

Sean

Re: Ultrasonic Sensor

Posted: Friday 15 January 2016 22:11
by dwmw2
Please see https://github.com/merbanan/rtl_433_tests

Capture a few packets with 'rtl_433 -a -t' as described there, and ideally add them to a new subdirectory under tests/oil_watchman/ and submit a pull request. Failing that, just mail them to me or make them available please.