0

我想将我在 Flash Pro 中编写的 as3 应用程序中的整数数组发送到 Arduino Uno,后者将使用它们连续定位和重新定位 5 个伺服系统。所以发送 15 个整数将定位 5 个舵机,然后重新定位它们,然后再次重新定位它们,然后循环回到第一个位置,依此类推。然后我会随时发送一个新数组替换旧数组。

所以我已经在它们之间配置好了我的 tinkerproxy(感谢 Mike Chambers 和其他人),并且我已经编写了双方,因此在与串行监视器接口时它们看起来工作正常。但我无法让他们正常交谈。

我的问题很简单......我认为......这是如何让 as3 在数组中或之后发送“换行符”或其他一些“结束”信号,以便 Arduino 草图(使用 serialEvent 和 parseInt 获取整数时它们被发送),在接收到它时,可以跳过 parseInt 并做其他事情 - 在这种情况下,进入循环并控制这些讨厌的伺服器。

可能附加的代码太多了,我希望有人能提供帮助。我很缺乏经验,你可能已经猜到了......

阿杜诺

/* 
   this sketch developed from arduino Tutorials ReadASCIIString + SerialEvent
   serialEvent can receive an array - 'buff' - of values from serial monitor
   loop can get those values and print some of them to prove it
   but I can't get Flash Pro (as3) to send the array: something to do with end of message character?
*/
#include <Servo.h>

int buff[100];//an array to hold integers from serial(arbitrary larger than ever needed size)
int j; //used to increment serial integer receipt in serialEvent
int patternLength;//=# of integers delivered over serial port, if followed by E or newline

void setup()
{
Serial.begin(9600);
Serial.setTimeout(2147483647);//25 days! so parseInt doesn't default to sending zeros every second
Serial.println("ready to go");//prints ok
}

void loop()
{
   for(int i=0; i<patternLength-4; i=i+5)//feed sets of 5 integers into 5 servos then repeats
    Serial.println(buff[i]);//prints 1st, 5th, 10th etc integer then repeats
    delay(1000);//so I can see it happening slowly enough
}//loops indefinitely until serialEvent interrupts to send new buff array values

void serialEvent()
{
     while(Serial.available()>0)
     {
     buff[j] = Serial.parseInt();
 Serial.println(buff[j]);//prints all integers sent if eg ','sent after last one
 j++;


 //if (Serial.read() == '\n')//works if serial monitor is set to 'newline' on sending
 if (Serial.read() == 'E')//works if no 'newline' + sending eg 1,2,3,4,5,6,7,8,9,10E

 //BUT how to send the equivalent of one of the above two 'endings' from Flash???
 //so that this part of the code executes
     {
     patternLength = j;  
     Serial.println("go to loop");
     j=0;//reset the index so next array sent replaces this one in 'buff' 
     }
 }

}

FLASH PRO ACTIONSCRIPT as3

/*
Simple Example that connects to an Arduino (via TinkerProxy) and sends
an array of integers for it to use. That doesn't work......

adapted from FlashBlink Created by Mike Chambers:

http://www.mikechambers.com/blog/2010/08/04/getting-started-with-flash-and-arduino/
*/


import flash.events.Event;
import flash.display.Sprite;
import flash.net.Socket;
//import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
//import flash.events.SecurityErrorEvent;
import flash.utils.Endian;
import flash.events.MouseEvent;

//my example of an array of integers I want to send to the arduino
var pattern:Array = [10,11,12,13,14,15,16,17,18,19,20];

//socket we will use to connect to TinkerProxy
var _socket:Socket;

//Address where TinkerProxy is located. Will usually be
//localhost / 127.0.0.1
var _proxyAddress:String = "127.0.0.1";

//port TinkerProxy is listening on
var _proxyPort:uint = 5331;

function onAddedToStage():void
{
    removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);

    //create a Sprite to add to the stage.
    //This will be a simple button
    var s:Sprite = new Sprite();

    //draw a green square in the Sprite
    s.graphics.beginFill(0x00FF00);
    s.graphics.drawRect(0,0, 200,100);
    s.graphics.endFill();

    //Add Sprite to the display list
    addChild(s);

    //position it
    s.x = 50;
    s.y = 50;

    //listen for when the user clicks the Sprite
    s.addEventListener(MouseEvent.CLICK, onClick);

    _socket = new Socket();

    //Register for socket events

    //socket connected
    _socket.addEventListener( Event.CONNECT, onConnect );           

    //socket closed
    _socket.addEventListener( Event.CLOSE, onClose );           

    _socket.endian = Endian.LITTLE_ENDIAN;

    //connect
    _socket.connect(_proxyAddress, _proxyPort);
}

//called when we connect to the proxy server
function onConnect(event:Event):void
{
    trace("Socket Connected");
}

//called when the user clicks the button on stage
function onClick(event:MouseEvent):void
{
    trace("onClick");

    //make sure we are connected to the socket
    if(!_socket.connected)
    {
        //if not, don't do anything
        trace("You must be connected to send a command to the Arduino.");
        return;
    }

    var ENDOF:String = "E";

    for(var j:int = 0; j < pattern.length; j++)
        { 
        _socket.writeUTFBytes(pattern[j]); //send pattern array to Arduino
        trace(pattern[j]);//trace what I think I've just sent
        }
        //then send something as a last character - not an integer.
        _socket.writeUTFBytes(ENDOF);//send this string value to arduino
        trace("should have just sent an E, and sends an: " + ENDOF);
        //but how do I send this E conjoined to the last integer of the pattern array
        //so that Arduino responds by jumping out of serialEvent back to the loop?

        //flush the socket. Not really necessary, but here for forward compatibility.
        _socket.flush();
}

//called when the socket is closed
function onClose(event:Event):void
{
    trace("Socket Closed");
}

onAddedToStage();
4

1 回答 1

0

您的 AS3 看起来相当到位。一个小问题,onAddedToStage()您要从您从未注册的阶段中删除事件侦听器。如果您真的希望该代码仅在将时间线添加到舞台后触发,请将第 114 行替换为以下内容:

addEventListener(Event.ADDED_TO_STAGE, onAddedToStage)

至于您的 Arduino 代码,我并不精通它使用的语言(某种 C 语言?),所以如果您了解更多,请随意忽略以下内容。

  • 您没有将循环封装在直通for线上2224
  • 您开始while在线封装循环30,但忘记在线关闭它34
  • 您声明j了,但直到 line44之后才初始化它的值,它将while在 line 上的循环中使用33

最后,回答你的核心问题。您已经知道换行符写为\n,因此您似乎很难从Serial.read(). 阅读文档后,我找不到任何数据类型,所以我假设您正在处理 ByteArray 或 String。假设它是一个字符串,我的第一反应是使用 String.split() 将其拆分为一个数组,但这不是 String API 可用的函数。 其他人(但是)已经编写了它,我相信它会简化问题,假设字符串和整数可以愉快地共存于这些对象类型中。

相反,由于您已经知道这些数字的大小是五重组,而不是使用while循环(行29),您可以只使用 afor如下:

#include <Servo.h>

int buff[100];
int j;
int patternLength;

void setup() {
    Serial.begin(9600);
    Serial.setTimeout(2147483647);
    Serial.println("ready to go");
}

void loop() {
    for(int i=0; i<patternLength-4; i=i+5) {
        Serial.println(buff[i]);
        delay(1000);
    }
}

void serialEvent() {
    if (Serial.available() > 0) {
        // This gaurantees we only pull the first 15 Ints into our buff array
        for (int k=0; k<15; k++)  {
            buff[j] = Serial.parseInt();
            Serial.println(buff[j]);
            j++;
        }

        patternLength = j;  
        Serial.println("go to loop");
        j=0;//reset the index so next array sent replaces this one in 'buff'
    }
}

如果上面的内容没有为您标记,您可能需要调试您实际从 Stream 中读取的值并在 if 语句中进行测试37

Serial.println("Reading: " + Serial.read());

希望能帮助到你。

-干杯

于 2013-10-31T21:56:33.777 回答