0

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

我不确定如何处理数据,以便每当检测到某个值时,处理中就会发生一个事件。

编辑:有人建议我的问题是调用myMovie.loop()是阻塞调用,这意味着指令指针 invoid setup()将保持在myMovie.loop(). 指针将调用void Draw()and 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); 
  }
}  

下面是我的 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();
       }
    }

基本上,我使用 Arduino Uno 来计算电脑风扇的速度。如果风扇保持在 3600 rpm,那么我想要播放电影。如果它低于该值,我希望电影停止播放。我的 Arduino 草图正在工作(我可以在串行端口上很好地读取数据),但由于某种原因,我无法通过处理来做到这一点;似乎没有数据进入。我基于 Arduino 附带的系列示例,但似乎还没有任何效果。

4

2 回答 2

1

I think you have multiple problems here and need to separate them slightly. The first thing I would do is remove the arduino from the equation for now and verify that the processing side of things works properly first. Have the processing sketch simply pretend to itself that it is getting the right data for now and then you can more easily figure out if you have any blocking issues. The next thing to do is to sort out the photodiode circuit. From what I gather, you have a resistor between ground and the 'cathode' on the photodiode, you then have the anode attached to the analog input. I'm fairly sure this won't work.

The way it should work (I think) is that you connect your anode to ground and your cathode to the analog input pin. Then connect that same analog input pin to your power supply voltage via a fairly high resistance. (somewhere in the order of megaohms). By doing this, you have the analog input at the supply voltage when it is dark as the photodiode is reversed biased and is not producing a voltage. When there is light, there will be a small amount of current allowed through the diode, with a large enough resistor, this current to ground will cause a small volt drop to appear across the diode and so you will measure a slightly lower value on your input. I think that should work. There is also a difference between a photodiode and a phototransistor, make sure you know which one you have, a photodiode should also work in the circuit described where the collector replaces the cathode and the emitter replaces the anode. This may need a smaller resistor on the collector side however, 1MOhm and beyond would be too high, somewhere around 1k. of course, if you are sure you have a photodiode then this doesn't matter.

But this is all just me guessing (ish). I've not used photodiodes or phototransistors much.

Once you are sure you are getting good values from the arduino/photodiode side of things, and you know that you have a working processing sketch, then you can try and connect the two.

于 2014-09-25T18:19:30.567 回答
0

Try print(val); in the void draw() function to see if any values gets sent to the console. I'm guessing that val never changes from 0.

Also I don't think you should use both port.bufferUntil('\n'); and port.readStringUntil('\n');

Try only one at a time. Not sure if that makes a difference but in the docs they only use one at a time that I could see.

I would also change

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

to

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

Hope this helps.

于 2014-09-16T17:40:47.010 回答