Serial port 通过处理读取Arduino串行数据

Serial port 通过处理读取Arduino串行数据,serial-port,arduino,processing,microcontroller,arduino-uno,Serial Port,Arduino,Processing,Microcontroller,Arduino Uno,我试图做的是从我用Arudino制作的转速表电路中读取连续的数据流,然后将其输入到处理中;我已经使用下面的代码成功地完成了: 我不确定如何处理数据,以便在检测到某个值时,在处理过程中发生事件 编辑:有人建议关闭,因此我的问题是对myMovie.loop()的调用是一个阻塞调用,这意味着void setup()中的指令指针将保持在myMovie.loop()上。指针将调用void Draw()和movieEvent,但永远不会到达启动串行端口的线路 port = new Serial(this,

我试图做的是从我用Arudino制作的转速表电路中读取连续的数据流,然后将其输入到处理中;我已经使用下面的代码成功地完成了:

我不确定如何处理数据,以便在检测到某个值时,在处理过程中发生事件

编辑:有人建议关闭,因此我的问题是对
myMovie.loop()
的调用是一个阻塞调用,这意味着
void setup()
中的指令指针将保持在
myMovie.loop()
上。指针将调用
void Draw()
movieEvent
,但永远不会到达启动串行端口的线路

port = new Serial(this, "/dev/tty.usbmodem1411", 9600); 
port.bufferUntil('\n');
建议的解决方案是将这些行移到
void Draw()
的顶部,并将
myMovie.loop
作为
void setup()
的最后一行。我尝试了这一点(下面的代码反映了这一变化),但在处理过程中,我仍然将“0.0”作为串行输入读取,但在Arduino中获得了正确的数据

下面是我的处理代码:

import processing.video.*; 
import processing.serial.*; 


Serial port; 
Movie myMovie; 

//try as a float?
double val = 0; 

void setup() 
{  
 //create screen
 size(320, 240); 
 background(0); 
 //load movie
 myMovie = new Movie(this, "countdown.mov"); 


 // print a list of all available ports 
 println(Serial.list()); 

 // choose the port to which the Arduino is connected 
 // on the PC this is usually COM1, on the Macintosh 
 // this is usually tty.usbserial-XXX 
 port = new Serial(this, "/dev/tty.usbmodem1411", 9600); 


 ///(1) if this line used, no information is read
// port.bufferUntil('\n');  

 myMovie.loop(); 
}    




 void draw() { 
 if (0 < port.available()) { 

 ///(2) If this line is used, '0.0' is read once and displayed in serial output
 String strData = port.readStringUntil('\n'); // string representation of value

 //TEST
 print(val);

 val = Double.parseDouble(strData); // double from string data
}

 image(myMovie, 0, 0); 
}




void movieEvent(Movie m) {
 m.read();
if (val >= 3600) {
   myMovie.speed(1); 
}
else { 
   myMovie.speed(0); 
  }
}  
导入处理。视频。*;
输入处理。串行。*;
串口;
电影我的电影;
//试一试浮球?
双val=0;
无效设置()
{  
//创建屏幕
尺寸(320240);
背景(0);
//加载电影
myMovie=新电影(这是“countdown.mov”);
//打印所有可用端口的列表
println(Serial.list());
//选择Arduino连接到的端口
//在PC上,这通常是COM1,在Macintosh上
//这通常是tty.usbserial-XXX
端口=新的串行端口(该端口为“/dev/tty.usbmodem1411”,9600);
///(1) 如果使用此行,则不读取任何信息
//port.bufferUntil('\n');
myMovie.loop();
}    
void draw(){
如果(0=3600){
我的电影。速度(1);
}
否则{
myMovie.speed(0);
}
}  
下面是我的Arduino代码:

 //// This example shows one way of creating an optoswitch
    //// using an IR LED as emitter and an IR LED receiver as
    //// light sensor.
    ////
    ////           + GROUND                                 +GROUND          
    ////           |                                        |  
    ////           <                                        < 
    ////           > 220 ohm resistor                       > 220 ohm resistor
    ////           <                                        <      
    ////           |                                        |  
    ////           |                                        |
    ////         -----                                    -----
    ////          / \    >>IR LED emitter >>>>>>>>>>>>>>>>  / \   IR LED receiver
    ////         -----                                    -----
    ////           |                                        |
    ////           |                                        |
    ////           + +5VCD                                  +  ANALOG INPUT 0
    ////
    ////
    ////
    ////<a href="http://playground.arduino.cc/Learning/Tachometer" target="_blank" rel="nofollow">http://playground.arduino.cc/Learning/Tachometer</a>


    int val;
    long last=0;
    int currentStatus=LOW;
    int previousStatus=LOW;
    int count=0;

    int sens=85;  // this value indicates the limit reading between dark and light,
                  // it has to be tested as it may change acording on the 
                  // distance the leds are placed.
    int nSpokes=7; // the number of blades of the wheel

    int milliseconds=500; // the time it takes each reading



    void setup()  
    {
      Serial.begin(9600);
      pinMode(13,OUTPUT);
    }

    void loop()
    {
      val=analogRead(0);
      if(val<sens)
        currentStatus=LOW;
       else
        currentStatus=HIGH;
       digitalWrite(13,currentStatus); //as iR light is invisible for us, the led on pin 13 
                              //indicate the state of the circuit.

       if(previousStatus!=currentStatus){  //counts when the state changes from (dark to light) or 
                         //from (light to dark), remmember that IR light is invisible for us.
         count++;
         previousStatus=currentStatus;
       }
       if(millis()-last>=milliseconds){
         double rps=((double)count/nSpokes)/2.0*1000.0/milliseconds;
         double rpm=((double)count/nSpokes)/2.0*60000.0/(milliseconds);
    //     Serial.print((count/2.0));Serial.print("  RPS ");Serial.print(rps);
    //     Serial.print(" RPM");
    //     Serial.print(rpm);
    //     Serial.print("  VAL ");Serial.println(val); 
         Serial.println(rpm);
         count=0;
         last=millis();
       }
    }
///此示例显示了创建光电开关的一种方法
////使用红外LED作为发射器,使用红外LED作为接收器
////光传感器。
////
////+接地+接地
////           |                                        |  
////           <                                        < 
////>220欧姆电阻器>220欧姆电阻器
////           <                                        <      
////           |                                        |  
////           |                                        |
////         -----                                    -----
/////\>>红外LED发射器>>>>>>>>>>>>>>/\IR LED接收器
////         -----                                    -----
////           |                                        |
////           |                                        |
////++5VCD+模拟输入0
////
////
////
////
int-val;
longlast=0;
int currentStatus=低;
int-previousStatus=低;
整数计数=0;
int sens=85;//该值表示黑暗和光明之间的极限读数,
//必须对其进行测试,因为它可能会根据
//LED放置的距离。
int nSpokes=7;//车轮的叶片数
整数毫秒=500;//每次阅读所需的时间
无效设置()
{
Serial.begin(9600);
pinMode(13,输出);
}
void循环()
{
val=模拟读数(0);
如果(val=毫秒){
双rps=((双)计数/nspoke)/2.0*1000.0/毫秒;
双rpm=((双)计数/nspoke)/2.0*60000.0/(毫秒);
//Serial.print((count/2.0));Serial.print(“RPS”);Serial.print(RPS);
//串行打印(“RPM”);
//串行打印(rpm);
//Serial.print(“VAL”);Serial.println(VAL);
串行打印LN(rpm);
计数=0;
last=millis();
}
}
基本上,我用Arduino Uno来计算电脑风扇的速度。如果风扇转速保持在3600转,那么我想播放一部电影。如果低于这个值,我希望电影停止播放。我的Arduino草图正在工作(我能够在串行端口上很好地读取数据),但由于某些原因,我无法通过处理来实现这一点;似乎没有收到任何数据。我是根据Arduino附带的一系列示例编写的,但似乎什么都不管用

尝试
打印(val)
另外,我认为不应该同时使用
port.bufferUntil('\n')
port.readStringUntil('\n')

一次只试一个。我不确定这是否有什么不同,但在文档中,我可以看到他们一次只使用一个

我也会改变

 if (val == 0) { 
   myMovie.speed(0); 
 } 
 else if (val >= 3600) 
   myMovie.speed(1); 
 else { 
   myMovie.speed(0); 
 }


希望这能有所帮助。

我认为您在这里遇到了多个问题,需要将它们稍微分开。 我要做的第一件事是从等式中删除arduino,然后首先验证事物的处理端是否正常工作。让处理草图简单地假装它现在正在获取正确的数据,然后您就可以更容易地找出是否存在任何阻塞问题。 下一步要做的是整理光电二极管电路。据我所知,在接地和光电二极管上的“阴极”之间有一个电阻器,然后将阳极连接到模拟输入端。我敢肯定这行不通

它的工作方式(I)
if (val >= 3600) {
   myMovie.speed(1); 
}
else { 
   myMovie.speed(0); 
}