Announcement

Collapse
No announcement yet.

Serial Port Communication Help Needed Using a Sonic Distance Sensor

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Serial Port Communication Help Needed Using a Sonic Distance Sensor

    I am in need of some help as I'm out of my area of expertise here!

    I recently purchased THIS Ultrasonic Range Finder. I'm trying to use the serial port interface and place the range data into a HomeSeer device.

    HERE is the data sheet for that sensor.

    I have COM1 connected to the sensor as follows. Pin#2 to "TX", Pin#5 to "GND" and a wall wart outputing 5.45 volts DC to pins "+5" and "GND". I am leaving "RX" on the sensor unconnected.

    When I connect to the sensor via HyperTerminal I get an "R" followed by three digits which represents "inches" as stated in the data sheet. I can move my hand up and down over the sensor and it registers the correct distance.

    From the data sheet:
    Range information is sent in the form of a capital "R", followed by three ASCII character digits representing the range in inches up to a maximum of 255, followed by a carriage return (ASCII 13). The RS 232 data is sent immediately after an object is detected.
    So now I'm trying to create a script using HomeSeer ver 1.7.44. I have installed 1.7.44 on a test machine (Windows XP with all latest SP's and updates) so I don't break my regular HomeSeer machine. Also, nothing else can conflict as this is the only scripting/application that this test HomeSeer is running.

    I created two scripts as shown below. "Sonic1.txt" opens the Com Port One and (at least in my mind) gets the data until it receives a carriage return (ASCII 13), then calls the data handling subroutine "sonic" which is in "sonic2.txt" script.

    There it places the "data" into HomeSeer device "R1" (I previously created a virtual R1 device in HomeSeer). Then that script closes the Com Port.

    I created an event that runs the script "sonic1.txt" every ten seconds.

    All works well till after a few minutes, then I get an error stating that "Com1 is already open".

    I don't know what is wrong but I believe it has something to do with the way I'm opening and closing the com port, or the way I'm expecting the last ASCII character in my "hs.opencomportex" statement in the sonic1.txt script.

    I know I get the "R" with the inches, but I wanted to get this working first before I figure out a way to trim the string to get the inches data only into the HomeSeer device.

    Is this the best way to get this data from the sonic sensor? I don't need fast, but I'm not sure how to control its receive line to request only one reading. I thought the hsopencomportex statement would let me only read this device once as I'm looking for a carriage return as the terminating string (even though the sonic sensor is constantly spitting out data on the serial port).

    sonic1.txt script: (runs every ten seconds via a HomeSeer Event)

    Code:
    sub main() 
    
    e=hs.OpenComPortex(1,"9600,n,8,1",1,"sonic2.txt","sonic", chr(13), 1)
    
    if e<> "" then msgbox "Error opening COM1: " & e
    
    end sub
    sonic2.txt script:

    Code:
    sub sonic (data)
    
    hs.setdevicestring "r1", data    'write string to Homeseer device "r1"
    
    hs.CloseComPort(1)
    
    end sub
    Help as always is very appreciated! Oh yes, I did close down HyperTerminal before operating the scripts so nothing else is accessing the serial port #1.

    Thanks,

    BSR
    Last edited by BraveSirRobbin; May 27th, 2006, 10:56 PM.
    --------------------------------------------------
    **** Do You "Cocoon"? ****

  • #2
    Unless you have a need to have multiple applications access that sensor then I would open the com port in your startup.txt and close it in shutdown.txt. You never need to worry about timing associated with open and close. The data will appear in chunks that you can stuff into a string and parse the string looking for complete segments.

    Comment


    • #3
      Michael:

      Thanks for the quick response!

      I re-arranged my setup as follows. I now have the following in the startup.txt file:

      Code:
      sub main
      
      e=hs.OpenComPortex(1,"9600,n,8,1",1,"sonic2.txt","sonic", chr(13), 1)
      
      if e<> "" then msgbox "Error opening COM1: " & e
      	
      end sub
      And the following in my shutdown.txt file:
      Code:
      hs.CloseComPort(1)
      I also modified the sonic2.txt file as follows (took out the hs.CloseComPort(1) command):
      Code:
      sub sonic (data)
      
      hs.setdevicestring "r1", data    'write string to Homeseer device "r1"
      
      end sub
      I restarted HomeSeer. I noticed that the device updates almost instantly, but on the bottom msg box area of HomeSeer (where it shows if an event is running) I noticed that it is rapidly and continually flashing:

      "scripts running sonic2.txt".

      At least that's what I think it is saying as it is flashing by so fast that I really cant read it.

      Is this a problem? Is it OK to "continually" run a script in HomeSeer like this? Would it conflict with any of my regular setup scripts once I convert this to my regular HomeSeer machine?

      I guess I'm just a little nervous as it is continually running like this (though CPU useage is only around five percent that is being used by HomeSeer).

      Thanks again,

      BSR
      --------------------------------------------------
      **** Do You "Cocoon"? ****

      Comment


      • #4
        I further modified the data handling script to eliminate leading zeros as shown below. I realize there may be many, many ways of doing this more efficiently (please let me know).

        Code:
        sub sonic (data)   'This data handling routine is referenced in the HomeSeer Startup Script (startup.txt)
        
        'Note: "data" is in the text form of "R" followed by a three digit number in inches (006 to 255).
        
        dim data_trim
        dim zero_check1
        dim zero_check2
        
        'Format data so any leading zeros are eliminated:
        
        zero_check1 = Left (data, 2)  	'Check for "R0xx"
        zero_check2 = Left (data, 3)	'Check for "R00x"
        
        
        If zero_check2 = "R00" then   ' If the reading is under 10 inches (R006 to R009)
        	data_trim = Right (data, 1)
        End If
        
        
        If zero_check1 = "R0" and zero_check2 <> "R00" then   'If the reading is 10 inches to 99 inches (R010 to R099)
        	data_trim = Right (data, 2)
        End If
        
        
        If zero_check1 <> "R0" and zero_check2 <> "R00" then  'If the reading is 100 inches to 255 inches (R100 to R255)
        	data_trim = Right (data, 3)
        End If
        
        hs.setdevicestring "r1", data_trim    'write string "data_trim" to Homeseer device "r1"
        
        end sub
        --------------------------------------------------
        **** Do You "Cocoon"? ****

        Comment


        • #5
          Based upon your observation it looks as if the sensor is continually sending data which does not hurt HS, but it does put a load that may not be desirable.

          To answer your last question first...

          Code:
          sub sonic(data)
              if left(data,1) = "R" and len(data) = 4 then
                  sDigits = mid(data,2)
                  if isNumeric(sDigits) then
                      hs.setdevicestring "r1", cstr(cint(sDigits))
                      hs.setdevicevalue "r1", clng(sDigits)
                  end if
              end if
          end sub
          You could also made is simplier if you did not do validity checking and just let the err object branch you out of bad data

          Code:
          sub sonic(data)
              hs.setdevicestring "r1", cstr(cint(mid(data,2)))
          end sub
          Many serial devices will have hardware flow control discretes such as DTR, RTS, etc. I think HS supports control of these from script. I do not know if your sensor supports it or not. I also do not know if you are looking for immediate distance measurements or just want to sample as some fixed period. If the sensor supports it then you can trigger the sampling of the sensor in a periodic event where the event turns on the flow discrete and the collection of the sample from the comm event turns it back off.

          With knowing nothing more and assuming a reasonble baud rate then I would probably just run it full-out like you are doing. Of course if I was doing it then my sensor would be another xAP node and messages would be delivered based upon some criteria for delta distance. This would put the burden on the xAP node to deal with the comm interrupts and let the LAN deliver the events when distance changes. If you got your other xAP goodies working then I can give you this node if you are interested.

          Comment


          • #6
            WOW, Michael! Talk about the difference between an amateur and a professional!!

            Your method worked perfectly and I appreciate the time you took to post it.

            This sensor operates at 9600 baud and I really don't see any way of controlling "when" it sends data (other than controlling the RX line and holding it high somehow for a few milliseconds per reading).

            I'm not looking at any fast updating for my current application, but I can see where the fast, immediate response would be usefull, so I will just let it go "flat out" as you suggested.

            For instance here in Las Vegas "heat profile" outdoor motion detectors are worthless. This sensor could be used as a outdoor motion detector that would be immune to the blazing sun. It could also be used as a garage parking indicator as well as other apps.

            Thanks again for the xAP offer. I have not had the time to incorporate any xAP nodes (work and family matters). I barely had the time to play around with this sensor today (which is why the posts were late into the evening ).

            I'll let you know when I need to incorporate this into xAP applications.

            Regards,

            BSR
            --------------------------------------------------
            **** Do You "Cocoon"? ****

            Comment


            • #7
              I really don't see any way of controlling "when" it sends data (other than controlling the RX line and holding it high somehow for a few milliseconds per reading)
              Can you just disable the serial receive function in HS and enable it when you want data?

              Comment


              • #8
                Originally posted by tonyno
                Can you just disable the serial receive function in HS and enable it when you want data?
                Tony;

                Thanks for the response. How would I go about doing that?

                Thanks,

                BSR
                --------------------------------------------------
                **** Do You "Cocoon"? ****

                Comment


                • #9
                  BSR,
                  If you only need the data at "desired times" then I would revert to opening the com port when you need the data and close it when you do not need it. Like this. Call event to open com port -- Process data as long as you need it -- Call event to close com port.
                  -Rupp
                  sigpic

                  Comment


                  • #10
                    Originally posted by Rupp
                    BSR,
                    If you only need the data at "desired times" then I would revert to opening the com port when you need the data and close it when you do not need it. Like this. Call event to open com port -- Process data as long as you need it -- Call event to close com port.
                    Thanks for the reply Rupp!

                    I was doing that methodology when I first started this but maybe I was not opening and closing the serial ports correctly. Look at my first post to this thread and you will see that when I was doing this everything would work correctly, then after a few minutes I would get a "Com Port Already Open" error.

                    Should I be doing that another way?

                    I did have my "test" HomeSeer running all through the night using Michael's method with no errors, but it does place a load on the HomeSeer machine (about five to eight percent CPU useage).

                    Regards,

                    BSR
                    --------------------------------------------------
                    **** Do You "Cocoon"? ****

                    Comment


                    • #11
                      The difference is you were reading data and closing the com port in the same script. The closing needs/could be moved to a different script.
                      -Rupp
                      sigpic

                      Comment


                      • #12
                        The sensor has a control line (labelled RX) that, when held low, will disable range finding (as mentioned above). I'm assuming that this also stops it from sending data.

                        You can connect the RTS or DTR line from the serial port to the RX input of the sensor. You can control the status of RTS and/or DTR from HS scripts. You can use this to turn the sensor on every so often. This will work fine with the version of the script that opens the port when HS starts up - rather than every time you need to get data.

                        You should use some sort of level converter between RX and RTS or DTR. The serial lines nominally use positive and negative voltages, not a positive voltage and ground. You can use a MAX232 or similar to do the conversion.

                        Comment


                        • #13
                          Thanks for all the suggestions. I think I'm going to take a very simple route here since I only need a reading once every dozen hours or so in my application. I'm just going to place the wall wart supplying the power on an applicance module and just switch the power on right before I want to take a reading, then switch it back off.

                          This way I only have to run two wires back to the computer (for the serial port lines) and I will not be taxing the HomeSeer system.

                          Also, the area I'm taking these readings can easily exceed 90 (& sometimes 100) deg. F so I only want this sensor on for a few seconds at a time.

                          Thanks again for all the help. It is very much appreciated!

                          BSR
                          --------------------------------------------------
                          **** Do You "Cocoon"? ****

                          Comment


                          • #14
                            Originally posted by BraveSirRobbin
                            I'm just going to place the wall wart supplying the power on an applicance module and just switch the power on right before I want to take a reading, then switch it back off.

                            BSR
                            BraveSirRobbin,

                            In switching the power on and off as you suggest, just be careful that you allow the unit to stabilize first. If it is like motion detectors, they must "get thier feet wet" per say and analyze what is there before being able to properly detect motion.
                            Not sure about this ultrasonic unit. It may or may not have to stabilize for several minutes before becoming accurate.
                            Most units of this nature are intended to be left on 24x7.

                            Steven

                            Comment


                            • #15
                              Yes, good advice Steven. I actually did some checks via my test bench setup and also looked at their documentation.

                              250mS after power-up, the MaxSonar-EZ1 is ready to accept the RX command. If the RX pin is left open or held high (as in my case) the sensor will first run a calibration cycle (48 mSec), and then it will take a range reading (48mSec).
                              This seems true with my testing as well.

                              I plan on doing something like turning power on, hs.WaitSecs about two or so seconds, take a reading, maybe store it in a variable, hs.WaitSecs another two seconds, take another reading, do a compare on the first reading and make sure it's not to far off, then record that number in the HomeSeer device.

                              All in all the unit should only be on for under ten seconds.
                              --------------------------------------------------
                              **** Do You "Cocoon"? ****

                              Comment

                              Working...
                              X