Topic closed
Ok this is really frustrating me. I a trying to tell the scratch program on my computer to set a variable but every time if gives me the error on scratch "message too big; bad field size?"
I looked at the instructions and sent what I though was the correct message.
//The socket is connected to my scratch program on my pc
//I want to set the player1Y variable to 201
mySocket.send('sensor-update "Scratch-player1Y" 201');
Every time I try this command in flash I get the same error in scratch. Can anyone help me out?
Offline
I seem to have absolutely no problems with receiving the messages. Its the sending that is giving me a hard time.
Offline
archmage wrote:
I seem to have absolutely no problems with receiving the messages. Its the sending that is giving me a hard time.
I believe what you need to do is send Scratch a 4-byte size field (that tells it the size of the message) followed by the actual message.
http://s3.amazonaws.com/jef.mindtouch.com/10053343/7/1?AWSAccessKeyId=1TDEJCXAPFCDHW56MSG2&Signature=/GsaCH6Gexn3CHX84PbFovlwWOY%3d&Expires=1232837274
so, for example, in Python, here is the way you would do it, and I think you'll see what it's doing even if you haven't done a lot of python.
def sendScratchCommand(cmd):
n = len(cmd)
a = array('c')
a.append(chr((n >> 24) & 0xFF))
a.append(chr((n >> 16) & 0xFF))
a.append(chr((n >> 8) & 0xFF))
a.append(chr(n & 0xFF))
scratchSock.send(a.tostring() + cmd)Or, in Java/Processing, it looks like this (though is less general):
void sendtoscratch(String dataOut) {
byte [] sizeBytes = { 0, 0, 0, 0 };
sizeBytes[3] = byte(dataOut.length());
for (int i=0; i<4; i++) {
ScratchClient.write(sizeBytes[i]);
}
ScratchClient.write(dataOut);
}I'm hopeless with Actionscript, so I'm probably no help in figuring out the exact syntax. The basic idea is: 1. figure out how big the message to scratch is, 2. build four bytes indicating the length, 3. concatenate the actual message, 4. send the combined string to scratch.
Hope this helps.
Last edited by chalkmarrow (2009-01-24 17:57:44)
Offline
Thank you for helping chalkmarrow, I think I am getting closer.
Here is the function I made in AS, it is similar to your java example.
function sendtoscratch(dataOut:String) {
var sizeBytes:Array = new Array(0, 0, 0, 0);
sizeBytes[3] = dataOut.length;
for (i=0; i<4; i++) {
mySocket.send(sizeBytes[i]); //send each element in the array to scratch
}
mySocket.send(dataOut); //This will send the dataOut variable to scratch
}
It seems mostly right to me except it still won't work. Is there anything obvious that I am doing wrong?
This is what the code does
1. creates an array
2. sets element 3 of the array to the length of the message
3. submit each element to scratch 1 by 1 in a for loop
4. submit the message to scratch
I get the same error though.
Last edited by archmage (2009-01-24 19:27:18)
Offline
archmage: Your code looks good to me. I'm thinking there might be a data type issue -- i.e., scratch expects a series of four bytes (which are generally 8-bit signed two's-complement integers), which of course is not necessarily the same as an array of integers (which I think may be 16 or 32 bits). I'm not sure what sort of primitive data types actionscript has, but that may be the issue. In the python example above, this is accomplished by using the "chr" function (which returns 8 bits). in Java, you can just use the byte data type. I'll fish around and see what I can find out.
Offline
Oh thats really bad news for me then if that is the case. I don't think you can assign a variable to a byte in actionscript.
Actionscript only has 3 variable types: number,boolean, and string.
Last edited by archmage (2009-01-24 23:50:19)
Offline
archmage wrote:
Oh thats really bad news for me then if that is the case. I don't think you can assign a variable to a byte in actionscript.
Actionscript only has 3 variable types: number,boolean, and string.
I'm wondering about the WriteByte method in flash.utils, or something like it:
http://help.adobe.com/en_US/AS3LCR/Flash_10.0/flash/utils/IDataOutput.html
update: I noticed that bytearrays are a part of AS3, but not AS2, if that is the version you're using.
Last edited by chalkmarrow (2009-01-25 00:07:33)
Offline
I am using flash 8 which only supports AS2. Maybe I should download the trial of flash cs4 to try the WriteByte method.
Offline
I'm wondering if the "chr" function in AS2 might work, much in the same way chr works in the Python code above.
Offline
As a follow-up, I notice that with Adobe AIR you can create cross-platform stand-alone apps with Flash and a few other tools, which means that might be a cool way to create interface "glue" programs for use with remote sensors.
Scratch Team: Can you move this to the Sensor Board forum? It might be useful for others playing around with Actionscript.
Offline
My school computers have a version of flash that supports AS3 so I tried programming a AS3 version of my script.
var xml_s=new XMLSocket();
xml_s.connect("localhost",42001);
xml_s.addEventListener(Event.CONNECT,xmlsocket);
xml_s.addEventListener(Event.CLOSE,xmlsocket);
xml_s.addEventListener(IOErrorEvent.IO_ERROR,xmlsocket);
function xmlsocket(Event):void {
switch (Event.type) {
case 'ioError' :
trace("can't connect");
break;
case 'connect' :
trace("connected");
break;
case 'close' :
trace("can't connect");
break;
}
}
sendtoscratch('broadcast "test"');
function sendtoscratch(dataOut:String) {
var sizeBytes:ByteArray = new ByteArray ();
sizeBytes[0]=0;
sizeBytes[1]=0;
sizeBytes[2]=0;
sizeBytes[3] = dataOut.length;
for (var i:Number=0; i<4; i++) {
xml_s.send(sizeBytes[i]);//send each element in the array to scratch
}
xml_s.send(dataOut);//This will send the dataOut variable to scratch
}Now scratch still gives me the message too big error. I am not very good at AS3 so I am not sure what I am doing wrong. I think that my byte array may have values that are not bytes. I will try to fix it next time I can use a school computer.
Offline
archmage: I just realized I had a copy of CS3, so I might be able take a look at the A3 code, though as I said I know nothing about Flash. Is the script pasted above the entire code?
Offline
chalkmarrow wrote:
archmage: I just realized I had a copy of CS3, so I might be able take a look at the A3 code, though as I said I know nothing about Flash. Is the script pasted above the entire code?
Yes, thats it. Put it on the first frame.
Offline
Thanks. I'll see if I can play with it this weekend. One thing that is likely a problem, I just noticed, is that the xmlSocket class is used, rather than the Socket class. Looking around, it appears that this class send and receives full xml-formatted objects. If I were to set up the socket, I would use something like the following, and then play around with the socket methods, such as writeBytes, writeUTFBytes, or the like. I'm not sure how exactly I would do that, but you'll probably have a better idea than I do once you look at the socket class methods, etc.
var s=new Socket();
var sizeBytes:ByteArray = new ByteArray();
var dataOut:String;
s.connect("localhost",42001);
s.addEventListener(Event.CONNECT,socket);
s.addEventListener(Event.CLOSE,socket);
s.addEventListener(IOErrorEvent.IO_ERROR,socket);
function socket(Event):void {
switch (Event.type) {
case 'ioError' :
trace("can't connect");
break;
case 'connect' :
trace("connected");
break;
case 'close' :
trace("can't connect");
break;
}
}Offline
Thanks for helping me out chalkmarrow. I usually don't use AS3 so this was kind of a learning experience for me. I copied the socket connection code from the internet so I didn't really realize that it was made for xml only. Hopefully we can get something working soon.
Offline
I think I need a bit more help because it isn't working.
This is the error flash gives me
ReferenceError: Error #1069: Property send not found on flash.net.Socket and there is no default value.
at sockets_fla::MainTimeline/sendtoscratch()
at sockets_fla::MainTimeline/sockets_fla::frame1()
connected
Here is my AS3 code
var s=new Socket();
var sizeBytes:ByteArray = new ByteArray();
var dataOut:String;
s.connect("localhost",42001);
s.addEventListener(Event.CONNECT,socket);
s.addEventListener(Event.CLOSE,socket);
s.addEventListener(IOErrorEvent.IO_ERROR,socket);
function socket(Event):void {
switch (Event.type) {
case 'ioError' :
trace("can't connect");
break;
case 'connect' :
trace("connected");
break;
case 'close' :
trace("can't connect");
break;
}
}
sendtoscratch('broadcast "test"');
function sendtoscratch(dataOut:String) {
sizeBytes[0]=0;
sizeBytes[1]=0;
sizeBytes[2]=0;
sizeBytes[3] = dataOut.length;
for (var i:Number=0; i<4; i++) {
s.send(sizeBytes[i]);//send each element in the array to scratch
}
s.send(dataOut);//This will send the dataOut variable to scratch
}I am not familiar with AS3 or sockets so this is kinda hard for me.
Last edited by archmage (2009-01-30 14:00:18)
Offline
I Can't Program At All. Only In Scratch. Everything else is too hard even squeak is too hard lol i can't even follow a tutorial right. AHHH. I'm More Of A Suggester. Archmage: I Hope You Can Do It! I Bet It Would Be Fun To Have That Part Of Scratch!
Offline
Thanks for the encouragement Magnie
If you want to program in a text language easily then try downloading and installing a cool program called hackity hack which lets you code in Ruby and comes with lessons.
Offline
Here's a link to the Hackety Hack site -- definitely worth checking out.
Offline
Cool I'll Check It Out.
Offline
Archmage: Nice. You were 99.9% there. There is no send method, so you have to use different "write" methods. And at the end, you have to use the flush() method to actually send out what you've written into the buffer (stuff doesn't get sent out automatically). I was able to get this basic code to work, maybe you can figure out something interesting to build on top of it:
var s=new Socket();
var dataOut:String;
s.connect("localhost",42001);
s.addEventListener(Event.CONNECT,socket);
s.addEventListener(Event.CLOSE,socket);
s.addEventListener(IOErrorEvent.IO_ERROR,socket);
function socket(Event):void {
switch (Event.type) {
case 'ioError' :
trace("can't connect");
break;
case 'connect' :
trace("connected");
break;
case 'close' :
trace("can't connect");
break;
}
}
sendtoscratch('broadcast "test"');
function sendtoscratch(dataOut:String) {
var sizeBytes:ByteArray = new ByteArray();
sizeBytes[0]=0;
sizeBytes[1]=0;
sizeBytes[2]=0;
sizeBytes[3] = dataOut.length;
for (var i:Number=0; i<4; i++) {
s.writeByte(sizeBytes[i]);//send each element in the array to scratch
}
s.writeMultiByte(dataOut, "us-ascii");
s.flush();
}Last edited by chalkmarrow (2009-01-30 20:47:49)
Offline
Oh wow it worked! Thanks so much Chalkmarrow!
Now all I have to do is get it to read data in from scratch which hopefully won't be too difficult.
Offline
Ah one more thing, it seems that flash doesn't let you connect sockets with the .swf files alone because of security issues. This is too bad because I had hoped to let the user to go online without downloading anything except the .sb file. It works when you convert the flash file to .exe though.
Last edited by archmage (2009-01-30 21:17:26)
Offline
Yeah. That's why I think Adobe AIR is going to be the way to deliver Flash programs in the future.
btw: Here's a variation of the code that reads from the socket (adding an event handler, and a function at the end):
var s=new Socket();
var dataOut:String;
s.connect("localhost",42001);
s.addEventListener(Event.CONNECT,socket);
s.addEventListener(Event.CLOSE,socket);
s.addEventListener(IOErrorEvent.IO_ERROR,socket);
s.addEventListener(ProgressEvent.SOCKET_DATA, dataInHandler);
function socket(Event):void {
switch (Event.type) {
case 'ioError' :
trace("can't connect");
break;
case 'connect' :
trace("connected");
break;
case 'close' :
trace("can't connect");
break;
}
}
sendToScratch('broadcast "test"');
function sendToScratch(dataOut:String) {
var sizeBytes:ByteArray = new ByteArray();
sizeBytes[0]=0;
sizeBytes[1]=0;
sizeBytes[2]=0;
sizeBytes[3] = dataOut.length;
s.writeBytes(sizeBytes);
s.writeMultiByte(dataOut, "us-ascii");
s.flush();
}
function dataInHandler(event:ProgressEvent):void {
var inString:String = s.readUTF();
trace(inString);
}Offline
Topic closed