简体   繁体   中英

High delay when using delay function in Processing/Arduino

When I use the delay function in

  if(rpm > (rpm_max - 50))
{
arduino.analogWrite(r,255);
arduino.analogWrite(g,0);
arduino.analogWrite(b,0);
delay(15);
arduino.analogWrite(r,0);
arduino.analogWrite(g,0);
arduino.analogWrite(b,0);
delay(15);
arduino.analogWrite(r,255);
arduino.analogWrite(g,0);
arduino.analogWrite(b,0);
delay(15);

}

It lags my code a lot. I'm unable to read the next rpm values to update my leds. How can blink the red led without stopping my whole code? I cant use threads because arduino doesnt allow it.

import controlP5.*;
import hypermedia.net.*;
import processing.serial.*;
import cc.arduino.*;

Arduino arduino;
int arduinoPos = 0;
int g = 11;
int r = 10;
int b = 9;
ControlP5 cp5;
UDP udpRX;

String ip="127.0.0.1";
int portRX=20777;

int pos;

void setup(){
  size(280,280);
  background(255);

  // Arduino connection and Servo output
  arduino = new Arduino(this, Arduino.list()[1], 115200);  // Your offset may vary
  //println(Arduino.list());
  arduino.pinMode(r,Arduino.OUTPUT);
  arduino.pinMode(g,Arduino.OUTPUT);
  arduino.pinMode(b,Arduino.OUTPUT);


  // Create new object for receiving 
  udpRX=new UDP(this,portRX,ip);
  udpRX.log(false);
  udpRX.listen(true);
}


void draw(){

}

void receive(byte[] data){

  // Function to output all the game data received
  fullOutput(data);


  // Time elapsed since game start
  pos = 0;
  float tTime = Float.intBitsToFloat((data[pos] & 0xff) | ((data[pos+1] & 0xff) << 8) | ((data[pos+2] & 0xff) << 16) | ((data[pos+3] & 0xff) << 24));

  // Lap time
  pos = 4;
  float lapTime = Float.intBitsToFloat((data[pos] & 0xff) | ((data[pos+1] & 0xff) << 8) | ((data[pos+2] & 0xff) << 16) | ((data[pos+3] & 0xff) << 24));

  // Speed, *3.6 for Km/h
  pos = 28;
  float speed = Float.intBitsToFloat((data[pos] & 0xff) | ((data[pos+1] & 0xff) << 8) | ((data[pos+2] & 0xff) << 16) | ((data[pos+3] & 0xff) << 24))*3.6;

  // Gear, neutral = 0
  pos = 132;
  float gear = Float.intBitsToFloat((data[pos] & 0xff) | ((data[pos+1] & 0xff) << 8) | ((data[pos+2] & 0xff) << 16) | ((data[pos+3] & 0xff) << 24));

  // Current lap, starts at 0
  pos = 144;
  float cLap = Float.intBitsToFloat((data[pos] & 0xff) | ((data[pos+1] & 0xff) << 8) | ((data[pos+2] & 0xff) << 16) | ((data[pos+3] & 0xff) << 24));

  // RPM, requires *10 for realistic values
  pos = 148;
  float rpm = Float.intBitsToFloat((data[pos] & 0xff) | ((data[pos+1] & 0xff) << 8) | ((data[pos+2] & 0xff) << 16) | ((data[pos+3] & 0xff) << 24))*10;

  pos = 252;
  float rpm_max = Float.intBitsToFloat((data[pos] & 0xff) | ((data[pos+1] & 0xff) << 8) | ((data[pos+2] & 0xff) << 16) | ((data[pos+3] & 0xff) << 24))*10;

  // Debug the received values
  gameDataOutput(tTime, lapTime, speed, gear, cLap, rpm,rpm_max);

  // Send the speed to the Servo
 // arduinoPos = (int)map(speed, 0, 350, 1, 180); // Note that I've set the max speed to 350, you might have to change this for other games
  //arduino.servoWrite(9, 180-arduinoPos);

   // arduino.analogWrite(r,255);
    //arduino.analogWrite(g,255);
   // arduino.analogWrite(b,255);

    arduino.digitalWrite(13,Arduino.HIGH);
  //ligar arduino firmdata analog simple
  if(rpm > (rpm_max - 50))
  {
    arduino.analogWrite(r,255);
    arduino.analogWrite(g,0);
    arduino.analogWrite(b,0);
    delay(15);
    arduino.analogWrite(r,0);
    arduino.analogWrite(g,0);
    arduino.analogWrite(b,0);
    delay(15);
    arduino.analogWrite(r,255);
    arduino.analogWrite(g,0);
    arduino.analogWrite(b,0);
    delay(15);

  }
  else if(rpm > (rpm_max - 2000) && (rpm < (rpm_max - 50)))
  {
    arduino.analogWrite(r,0);
    arduino.analogWrite(g,0);
    arduino.analogWrite(b,255);

  }
  else if(rpm > (rpm_max - 3000) && (rpm < (rpm_max - 2000)))
  {
    arduino.analogWrite(r,0);
    arduino.analogWrite(g,255);
    arduino.analogWrite(b,0);

  }
    else if(rpm  < (rpm_max - 3000))
  {
    arduino.analogWrite(r,0);
    arduino.analogWrite(g,0);
    arduino.analogWrite(b,0);

  }
}

void gameDataOutput(float tTime, float lapTime, float speed, float gear, float cLap, float rpm,float rpm_max){
  println("Total time: " + tTime);
  println("Lap time: " + lapTime);
  println("Speed: " + speed);
  println("Gear: " + gear);
  println("Current lap: " + cLap);
  println("RPM: " + rpm);
  println("RPM_MAX: " + rpm_max);
}

// Function that outputs all the received game data
void fullOutput(byte[] data){

  // Loop all the received bytes
  for(int i=0; i <= data.length-1; i++){

    // Values consist of 4 bytes
    if(i % 4 == 0){

      // Combine 4 bytes to the value
      float val = Float.intBitsToFloat((data[i] & 0xff) | ((data[i+1] & 0xff) << 8) | ((data[i+2] & 0xff) << 16) | ((data[i+3] & 0xff) << 24));

      // Output the 'raw' value
      println("Value received at position " + i + " = " + val);

    }
  }
}

To multitask effectively on an Arduino you are going to need to re-write your application to leverage interrupts. Interrupts are events, usually a timer or a pin change on the Arduino, that the processor responds to by starting special interrupt service routines (ISR). To have your application work as you intend, you should have your main application code run in loop() and have an ISR that is attached to a timer interrupt to blink the LED. Because the interrupt only runs when the timer event triggers, your main application is free to run without delay.

Interrupts can be a difficult concept to learn, but they are very powerful. This could be of use.

Alternatively, instead of delaying the entire time between blinks, allow your application to run and keep track of the time since the last blink. After every cycle of loop() check to see if the time since the last blink has exceeded your deadline. If it has, blink. Otherwise, continue running loop(). This would be of use.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM