Sign in to follow this  
Followers 0
RichardL

Scratch external sensor message comms with AutoIt

1 post in this topic

Scratch has immediate appeal for children to learn something about programming. Scratch has the option for TCP data connection and this allows it to interact with other programs and the real world.  These two AutoIt programs receive messages from Scratch and send messages to Scratch.

To see messages from Scratch all you have to do is have a scratch project running, with global variables changing value, and and some broadcast messages.  Run Scratch_Recv.au3 and see the messages in the console window.

To send messages to Scratch you have to prepare the scratch project to receive exactly the messages you are sending.  For broadcast messages this means creating a 'When I receive' item, new, and typing in the message.  For 'sensor-update' messages you have to send the message once, and then it appears in the 'sensor-value' drop-down list. For immediate viewing of the value I use a received broadcast message to trigger scratch to copy the received sensor value to a global variable.

#cs
Scratch_Recv.au3.  Reads messages from Scratch.

You have to turn on the TCP sensing.
http://wiki.scratch.mit.edu/wiki/Remote_Sensor_Connections
http://wiki.scratch.mit.edu/wiki/Remote_Sensors_Protocol
http://archive.scratch.mit.edu/forums/viewtopic.php?id=9458

In Scratch, in the 'sensing' library, 'right-click' on sensing(button pressed) and select 'enable remote sensor connections'

Scratch transmits values of global vars.
You get all vars when you connect, then the changes.

If you use a short loop delay, it frequently returns with no messages.  If you use a long delay, it returns with all the intervening messages.

Example output:
sensor-update "A" 3727 "B" 173 "C" 0
sensor-update "A" 3728
sensor-update "B" 174
#ce

Opt("MustDeclareVars", 1)

Func ConFmtWr($sCntrl, $a = "", $b = "", $c = "", $d = "", $e = "", $f = "", $g = "", $h = "")
    #cs
        Combined ConsoleWrite and StringFormat.
        First parameter is the control string, others are values
    #ce
    ConsoleWrite(StringFormat($sCntrl, $a, $b, $c, $d, $e, $f, $g, $h))
EndFunc


Local $socket
Local $iCount
Local $g_IP
Local $sMsg
Local $recv
Local $iMsgLen

;This is a CLIENT so start SERVER (Scratch) First (dummy).

$g_IP = "127.0.0.1"
TCPStartup()

; Connect to a Listening "SOCKET"
$socket = TCPConnect($g_IP, 42001)
If $socket = -1 Then
    MsgBox(0, Default, "Connect failed", 1)
    Exit
EndIf

$iCount = 0
While 1
    ; Try to receive (up to) 2048 bytes
    $recv = TCPRecv($socket, 2048, 1)

    While StringLen($recv) > 0
        ; You may get more than one message in the string, have to process each separately
        ;ConFmtWr("Rcv ~%s~\n", $recv)
        ; Get the Message Length
        $iMsgLen  = Int(StringMid($recv, 1, 10))
        $sMsg     = BinaryToString("0x" & StringMid($recv, 11, $iMsgLen * 2))
        ConFmtWr("%s\n", $sMsg)

        ; Cut of what we've processed, see if there's more.
        $recv = StringTrimLeft($recv, 10 + $iMsgLen * 2)
        If StringLen($recv) > 0 Then
            $recv = "0x" & $recv
            ;ConFmtWr("Rc2 ~%s~\n", $recv)
        EndIf
    WEnd
    $iCount += 1
    ;If $iCount > 30 Then Exit
    Sleep(1000)
    ConFmtWr("\n")
WEnd
#cs
Scratch_Send.au3.  Sends Messages to Scratch

You have to turn on the TCP sensing.
http://wiki.scratch.mit.edu/wiki/Remote_Sensor_Connections
http://wiki.scratch.mit.edu/wiki/Remote_Sensors_Protocol
http://archive.scratch.mit.edu/forums/viewtopic.php?id=9458

In Scratch, in the 'sensing' library, 'right-click' on sensing(button pressed) and select 'enable remote sensor connections'

#ce

Opt("MustDeclareVars", 1)

Func ConFmtWr($sCntrl, $a = "", $b = "", $c = "", $d = "", $e = "", $f = "", $g = "", $h = "")
    #cs
        Combined ConsoleWrite and StringFormat.
        First parameter is the control string, others are values
    #ce
    ConsoleWrite(StringFormat($sCntrl, $a, $b, $c, $d, $e, $f, $g, $h))
EndFunc

Func Scratch_Send($socket, $sMsg)
    ; Send a single message to Scratch.
    Local $iLen
    Local $iSLen

    $iLen = StringLen($sMsg)
    ConFmtWr("Msg: %-30s. ", $sMsg)
    ; Message starts with 3 zeros and length, then message
    ; (approximation good for messages up to 255 chars)
    $sMsg = Chr(0) & Chr(0) & Chr(0) & Chr($ilen) & $sMsg
    $iSLen = TCPSend($socket, StringToBinary($sMsg))
    ConFmtWr("Sent %3d bytes.\n", $iSLen)
EndFunc


Local $socket
Local $iCount
Local $g_IP
Local $sMsg

;This is a CLIENT so start SERVER (Scratch) First (dummy).

$g_IP = "127.0.0.1"
TCPStartup()

; Connect to a Listening "SOCKET"
$socket = TCPConnect($g_IP, 42001)
If $socket = -1 Then
    MsgBox(0, Default, "Connect failed", 1)
    Exit
EndIf


; Repeatedly send a sensor update and a broadcast message to scratch.

For $iCount = 1 To 1000

    $sMsg = StringFormat('sensor-update "D" %d', $iCount)
    Scratch_Send($socket, $sMsg)

    $sMsg = StringFormat('broadcast "Ex_AutoIt"')
    Scratch_Send($socket, $sMsg)

    Sleep(500)
Next

Share this post


Link to post
Share on other sites



Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0