2013-10-22 32 views
1

我正試圖在斜邊進入一定範圍時讓指示燈閃爍。但它似乎正在通過斜邊範圍的值超過它應該的次數。 LED在恢復正常之前閃爍約30-40次。不知道如何解決這個問題。指示燈閃爍的次數超過要求的數量

這是我的處理代碼:

import processing.serial.*; 

float r_height; // rise of the slope 
float r_width; // run of the slope 
float hypotnuse; // hypotenuse of the right angle 
int d = 20; // diameter of the chocolate 
float x ; // x of the chocolate destination 
float y ; // y of the chocolate destination 
int ledGlow; // how much the LED will glow 

Serial myPort; // serial port object 

void setup() { 

    size (510, 510); // size of the canvas 
    String portName = Serial.list()[8]; // my arduino port 
    myPort = new Serial(this, portName, 9600); 
    background (0); // color of the background 
    fill(204); // fill of the ellipse 
    ellipseMode (CORNER); //Ellipse mode 
    x = 0; //The placement on initial X for chocolate 
    y = 0; // the placement on initial Y for chocolate 
    ellipse (x, y, d, d); // ellipse 
    frameRate (30); 

} 

void draw() { 

    r_height = mouseY - y; // rise 
    r_width = mouseX - x; //run 
    hypotnuse = sqrt (((sq(r_height)) + (sq (r_width)))); //A^2 +B^2 = C^2 
    ledGlow = 255 - (round (hypotnuse/2.84)); // flipping the values 
    myPort.write(ledGlow); // The value being sent to the Arduino 
    println (ledGlow); 


    } 

這是Arduino的代碼:

float val; // Data received from the serial port 
int ledPin = 9; 


void setup() { 
    pinMode(ledPin, OUTPUT); // Set pin as OUTPUT 
    Serial.begin(9600); // Start serial communication at 9600 bps 
} 

void loop() { 
    if (Serial.available()) 
    { // If data is available to read, 
    val = Serial.read(); // read it and store it in val 

    // long steps2move = val.toInt(); 
    } 

    if (val > 230) { 

    analogWrite (ledPin, 255) ; // I have already tried digitalWrite 
    delay (100); 
    analogWrite (ledPin, 1) ; 
    delay (100); 

    } 

    else if (val < 230) { 
    analogWrite(ledPin, val); 
    } 
} 

修訂ARDUINO:

float val; // Data received from the serial port 
int ledPin = 9; // Set the pin to digital I/O 13 
unsigned long currentTime = 0; 
unsigned long pastTime  = 0; 
int currentState = 0; 
int wait   = 0; 

void setup() { 
    pinMode(ledPin, OUTPUT); // Set pin as OUTPUT 
    Serial.begin(9600); // Start serial communication at 9600 bps 
} 

void loop() { 
    if (Serial.available()) 
    { // If data is available to read, 
    val = Serial.read(); // read it and store it in val 

    // long steps2move = val.toInt(); 
    } 



    if (val > 230) { 

    pastTime = currentTime; 
    currentTime = millis(); 

    unsigned long timePassed = currentTime - pastTime; 
    if(timePassed >= wait) 
    { 
    switch(currentState) 
    { 
     case 0:     
     digitalWrite(9, HIGH); 
     wait = 500; 
     currentState = 1;  
     break;    

     case 1: 
     digitalWrite(9, LOW); 
     wait = 500; 
     currentState = 0; 
     break; 
    } 
    } 

    } 

    else if (val < 230) { 
    analogWrite(ledPin, val/2); 
    } 
} 

回答

2

處理代碼爲想必寫出來連續不斷地連續。但是,當斜邊進入你設定的範圍時,Arduino會有這些電話。我認爲這會導致它滯後,所以在清除延遲期間出現的串行數據積壓時,它會一直閃爍。

我認爲更好的方法是根本避免使用delay(),所以Arduino可以儘可能快地處理串行數據。在每個循環中,它應該首先獲取最新的串行數據(如果有的話)。基於此,它應該計算出並存儲LED當前應該做的事情(即它應該是閃爍的,否則應該是什麼亮度)。之後(不管是否實際接收到任何串行數據),LED可以從存儲狀態更新。切記不要使用delay()進行閃爍。相反,您可以跟蹤上次閃現的時間,並確定自那以後是否已過去100 ms(使用millis())。如果是這樣,請將其關閉。如果再過100 ms,請重新打開。

這種方法將串行數據的閃存時序分離,所以希望它能更好地工作。

+0

感謝您的回答!我看了一些關於milli如何工作的例子,我嘗試了一些東西,但現在它一直沒有工作。 Cna你請看看它,並告訴我我做錯了什麼? – tailedmouse

+1

不客氣!它看起來像你的新代碼中的問題是你每次循環更新'pastTime'。相反,嘗試只在實際打開或關閉LED時進行更新。這樣,它會記錄閃光之間的時間,而不是循環之間的時間。 –

+1

哦,我的上帝!它工作....謝謝噓!還有另一個問題呢!這真的很愚蠢,我正在劃分價值,但我忘了改變230!它現在有效! – tailedmouse