Bit and Byte manipulations for the hard of head

Rupp said:
The immediate response of the Rain8 is to execute any command then send back the same three bytes as an ACK.
If you are willing to ignore the ACK completely (i.e., just assume that it's working), it's a really simple script.
 
For right now I just want to echo/msgbox what gets sent back to ensure that I'm sending the correct information. I've set up my open com port statement in the statup.txt and setup my callback script to msgbox(data). Now I just have to figure out how to send the commands.
 
Rupp:

Here's a really quick, completely untested script. I did not run this through HS so it could have all sorts of errors (typos, etc.). It's late, I'm tired - that's my only excuse.

By the way, this is for HS 1.x. I don't know what might have changed for 2.x.

Set the com_port constant to the port you are using.
Call the startup subroutine from your HS startup script.
Call the shutdown subroutine from your HS shutdown script.
Call send_command from anywhere you want.

This assumes that you want to leave the port open to the device all the time. If not, you can put the startup and shutdown stuff in the beginning and end of the send_command subroutine (either as calls or by putting the code there).

This ignores the ACK message.

Code:
'com_test.txt

const com_port = 1

'put a call to this in the HS startup script

sub startup()
dim e

   e=hs.OpenComPort(com_port,"4800,N,8,1",1,,)
   if e<>"" then
      hs.WriteLog "comm_test","[Startup] Error opening COM" & com_port & ": " & e
   else
      hs.WriteLog "comm_test","[Startup] COM" & com_port & " opened."
   end if
end sub 'startup

'put a call to this in the HS shutdown script
sub shutdown()
dim e

   e = hs.CloseComPort(com_port)
   if e<>"" then
      hs.Writelog "comm_test","[Shutdown] Error closing COM" & com_port & ": " & e
   else
      hs.Writelog "comm_test","[Shutdown] COM" & com_port & " closed."
   end if
end sub 'shutdown


'You can call this from an event or within another script
'assumes message_string = "address|command"
'address = "1" - "254"
'zone    = "1" - "8"
'command = "ON" or "OFF"
'example: "32|1|ON"

sub send_command(message_string)
dim address_command
dim address, command, command_string, zone

   address_command = split(message_string,"|")
   address = cint(address_command(0))
   zone    = cint(address_command(1))
   command_string = address_command(2)
   if command_string = "ON" then
      command = 3
   else
      command = 4
   end if
   command = command*16 + zone

   hs.SendToComPort com_port,chr(64) & chr(address) & chr(command)

end sub 'send_command
 
Dang! Did you just type this up?

hs.SendToComPort com_port,chr(64) & chr(address) & chr(command)
If the address is 1 to I use chr(1)?
I'm not sure what goes in command either?
 
I updated my code in the post above. I accidentally posted the wrong version and deleted the right version. I think the one up there is ok now.

It's very limited. It ignores ack messages completely. It only allows you to send one type of command - to turn a single zone on or off.

The send_command subroutine gets a string containing the module address, zone number, and ON or OFF command (as described).

This should be close to working (if it doesn't work as is). It's late, I'm tired, and I didn't test anything (the code hasn't been anywhere except in Notepad) - that's my excuse.

The basic framework is there. It shouldn't be hard to add to.

I'd consider writing a separate subroutine for each type of command - at least for the special commands like "turn all zones off."
 
Smee,
If I wanted to simply echo the input would couldn't I simply have my callback script do this?

sub main(data)

msgbox(data)

end sub

I tried this and with the operating mode of the opencomport at 1 as you have in your example and it never fires. If I change it to 0 it fires but is empty.
 
Got it. I had to add a call to GetComPortData using mode 0. It now works perfectly. I really appreciate all of you guys help and thanks Smee for that script. I still can't believe you put that together that quickly. Now to get the timing down. The call to GetComPortData is running a bit quickly to grab the entire data.

Thanks again guys.
 
Handling the ack message is a bit tricky. In HS serial port stuff, the best way (I think) to handle incoming messages is if they can be recognized by a terminating character (typically carriage return, but it can be anything). In this situation, HS buffers all the incoming characters and only calls the call-back function when the complete string is available. This is easy to handle.

For the rain8net, it looks like it will only return three characters. You can set HS up to call the callback for every character received (I think this is mode 0). You need to accumulate the characters in a variable and check them after you've received 3. Or, you can write the wait for acknowledgement into the subroutine that sends the command. If you do this, you also need to worry about timing out if nothing comes in.

If you just want to display the characters that are coming in but not do anything with them, you should be able to do what you are doing with the msgbox. I think the data comes in as a character. Try writing the numerical value of the character instead. Offhand, I can't remember the function that converts characters to integers. But, if the function was XXX, you would use msgbox(XXX(data)).

{edit}

Glad to see you've got it working (almost). It's been a long time since I needed to use mode 0. I'm usually communicating with hardware I've built. I make sure the communications protocols coming into the computer terminate messages with chr(13) so that it's easy to use mode 1. I also try to keep most of the messages human readable (normal ascii characters). It makes it much easier to test things (including using HyperTerminal).
 
Smee,
Is it ok to use the same script to send the data and as the callbck script?
 
If you mean the same file, yeah, sure.

I do that with most (if not all) of mine. I lump everything related to the device or process together.

You just need to specify the name of the subroutine you will be calling as the callback (when you open the port).
 
Thanks. I just wasn't sure what would happen if the script was sending data at the same time it was receiving data.
 
Back
Top