Please help to make this code run faster and no delays

I need this part of the code to run with out any delay at all

void artDMXReceived(unsigned char* pbuff)  

Channel 2 of Artnet is running 4 seconds behind. How can I get this loop to run with instant control. Below is the entire code if there is any issues there let me know

#include <Ethernet.h>     //Standard Library
#include <EthernetUdp.h>  //Standard Library
#include <SD.h>
#include <max6675.h>

/*  set the desired subnet and universe (first universe is 0)
    sACN starts with universe 1 so subtract 1 from sACN universe
    to get DMX_UNIVERSE.                                           */
#define ARTNET_SUBNET 0          //defualt subnet is 0. Should not need to be changed.
#define ARTNET_UNIVERSE 1        //first universe being used
#define IPaddress 10, 27, 2, 95  //ipaddress
#define ETHERNET_BUFFER_MAX 640
#define ARTNET_ARTDMX 0x5000
#define ARTNET_ARTPOLL 0x2000
#define ARTNET_PORT 0x1936       //standard port
#define ARTNET_START_ADDRESS 18  //Byte 18 in the packet contains channel 1 values.
#define STATUS_LED 13            //shows us when we are receiving data
#define SDCARD_CONTROL 4         //set pin 4 to high to disable SD card interface on WiFi shield
#define NUM_RELAYS 4             //total number of relays used
#define REQ_BUF_SZ 50
#define WEBSERVER_PORT 80

File HMTL_file;

const int fuelVolume = 100;        // The amount of fuel in the firing chamber
const int thresholdPressure = 25;  // Threshold pressure in PSI
const int pilotTemp = 200;

unsigned int flowRate;         // The flow rate of fluid
unsigned int flowMilliLiters;  // The cumulative amount of fluid in milliliters

int channel1 = 0;  //channel 1
int channel2 = 1;  //channel 2

//Sensor Pins
const int flowSensor = 21;         // The pin number for the flow sensor
const int pressureSensorPin = A8;  // Pin connected to the pressure sensor
int thermoDO = 14;
int thermoCS = 15;
int thermoCLK = 16;

MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);

//Relay Pins array
const int pumpPin = 22;       // The pin number for the Fuel Pump
const int nitrogenPin = 24;   // Pin connected to the nitrogen valve
const int pilotPin = 26;      // Pin connected to the pilot light
const int firePin = 28;       // Pin connected to Fire Dragon Firing
const int firereadyPin = 30;  // Pin connected to Fire Dragon Firing


//Timer Setup
volatile byte currentcounter = 0;  //counter for data reception
byte previouscounter = 0;          //counter for data reception
unsigned long currentDelay = 0;    //current time value for ArtNet and E1.31 reception

unsigned long ms_from_start =0;
unsigned long ms_previous_read_time1   = 0;
unsigned long time1_interval=1000;
int firePin_state=0;
int pilotPin_state=0;
int nitrogenPin_state=0;
int pumpPin_state=0;

//Ethernet Configuration
byte mac[] = { 0x00, 0xDD, 0xEE, 0x01, 0x10, 0x90 };
IPAddress ip(IPaddress);                //IP address of ethernet shield
EthernetServer server(WEBSERVER_PORT);  // create a server at port
File webFile;                           // the web page file on the SD card
char HTTP_req[REQ_BUF_SZ] = { 0 };      // buffered HTTP request stored as null terminated string
char req_index = 0;                     // index into HTTP_req buffer

// buffer to hold E1.31 and Artnet data
unsigned char packetBuffer[ETHERNET_BUFFER_MAX];

// An EthernetUDP instance to let us send and receive packets over UDP
// aUDP creates a socket for an Art-Net port

EthernetUDP aUDP;

void setup() {
 
    pinMode(10, OUTPUT);// disable Ethernet chip
    pinMode(flowSensor, INPUT);
    pinMode(pressureSensorPin, INPUT);
    pinMode(pumpPin, OUTPUT);
    pinMode(nitrogenPin, OUTPUT);
    pinMode(pilotPin, OUTPUT);
    pinMode(firePin, OUTPUT);
    pinMode(firereadyPin, OUTPUT);
    pinMode(STATUS_LED, OUTPUT);      //Initialize status LED
    pinMode(SDCARD_CONTROL, OUTPUT);  //Initialize Pin 4

    digitalWrite(pumpPin, HIGH);      //set fuel pump to high for off
    digitalWrite(nitrogenPin, HIGH);  //set nitrogen to high for off
    digitalWrite(pilotPin, HIGH);     //set pilot lite to high for off
    digitalWrite(firePin, HIGH);
    digitalWrite(10, HIGH);// disable Ethernet chip
    digitalWrite(SDCARD_CONTROL, HIGH);  //Set pin 4 to high since we are not using the SD Card interface
  
  Ethernet.begin(mac, ip);  //Initialize Ethernet shield
  aUDP.begin(ARTNET_PORT);  //Open Artnet Port

  Serial.begin(9600);  //Serial for debugging
  server.begin();      // start to listen for clients

  Serial.println("Setup Complete");  //print complete

  // initialize SD card
  Serial.println("Initializing SD card...");
  if (!SD.begin(4)) {
    Serial.println("ERROR - SD card initialization failed!");
    return;  // init failed
  }
  Serial.println("SUCCESS - SD card initialized.");
  // check for index.htm file
  if (!SD.exists("index.htm")) {
    Serial.println("ERROR - Can't find index.htm file!");
    return;  // can't find index file
  }
  Serial.println("SUCCESS - Found index.htm file.");
}

/* artDMXReceived checks the universe and subnet then
   outputs the data to the relays */

void artDMXReceived(unsigned char* pbuff) {
  ms_from_start   = millis();
  if ((pbuff[14] & 0xF) == ARTNET_UNIVERSE) {
    if ((pbuff[14] >> 8) == ARTNET_SUBNET) {
     if (pbuff[ARTNET_START_ADDRESS + channel1] == 200)  //if channel value is 200
     {
        flowRate = pulseIn(flowSensor, HIGH);        // Read the flow rate
        flowMilliLiters += (flowRate / (60 * 7.5));  // Calculate the cumulative amount of fluid

        if (flowMilliLiters >= fuelVolume) {  // If the cumulative amount of fluid is greater than or equal to 1000 ml
          digitalWrite(pumpPin, HIGH);        // Turn off the relay
        } else {                              // If the cumulative amount of fluid is greater than or equal to 1000 ml
          digitalWrite(pumpPin, LOW);         // Turn off the relay
         }
        {
          
          if (flowMilliLiters >= fuelVolume) {
            digitalWrite(pilotPin, LOW);
          }
          int pressure = analogRead(pressureSensorPin);  // Read the pressure sensor
          pressure = map(pressure, 0, 1023, 0, 250);     // Map the reading to PSI
          if (flowMilliLiters >= fuelVolume) {
            digitalWrite(nitrogenPin, LOW);  // Keep the relay on
          }
          {
            if (pressure >= thresholdPressure) {  // If pressure is above threshold
            
              digitalWrite(nitrogenPin, HIGH);    // Turn off the relay
           }
          }
         }
        }
      } else {
           digitalWrite(pumpPin, HIGH);
            digitalWrite(nitrogenPin, HIGH);
            digitalWrite(pilotPin, HIGH);
      }
      double fahrenheit = thermocouple.readFahrenheit();
      double celsius = thermocouple.readCelsius();  
          int pressure = analogRead(pressureSensorPin);  // Read the pressure sensor
          pressure = map(pressure, 0, 1023, 0, 250);     // Map the reading to PSI      
         if (pbuff[ARTNET_START_ADDRESS + channel2] == 200 && pressure >= thresholdPressure && flowMilliLiters >= fuelVolume && fahrenheit > pilotTemp) {
            digitalWrite(firePin, LOW);  //Fire
            Serial.println("FIRING!!!!!!!!");
            delay(10000);
            digitalWrite(firePin, HIGH);
            digitalWrite(pumpPin, HIGH);
            digitalWrite(nitrogenPin, HIGH);
            digitalWrite(pilotPin, HIGH);
            (flowMilliLiters = 0);
            return (setup());
    }
  }
} 
 //end artDMXReceived

/*  artNetOpCode checks to see that the packet is actually Art-Net
    and returns the opcode telling what kind of Art-Net message it is.  */

int artNetOpCode(unsigned char* pbuff) {
  String test = String((char*)pbuff);
  if (test.equals("Art-Net")) {
    if (pbuff[11] >= 14) {               //protocol version [10] hi byte [11] lo byte
      return pbuff[9] * 256 + pbuff[8];  //opcode lo byte first
    }
  }
return 0;
}
/************************************************************************
  The main loop checks for and reads packets from the two UDP ethernet
  socket connections.  When a packet is recieved, it is checked to see if
  it is valid and then one of the DMXReceived functions is called, sending
  the DMX values to the output. There also is a timer to run a standby 
  program if no data is received for 30 seconds. 
*************************************************************************/

void loop() {
  if (currentcounter != previouscounter)  //has the value changed?
  {
    currentDelay = millis();           //store the time since the value has increased
    previouscounter = currentcounter;  //set the previous value equal to the current value
  }

  if (millis() - currentDelay > 30000)  //is the time since the value changed greater than 30 seconds?
  {
    digitalWrite(STATUS_LED, HIGH);  //turn LED off. Not receiving E1.31 or ArtNet.
  }

  // first check to see if a packet is available on the Art-Net port
  int packetSize = aUDP.parsePacket();
  if (packetSize) {
    aUDP.read(packetBuffer, ETHERNET_BUFFER_MAX);
    /* after reading the packet into the buffer, check to make sure
       that it is an Art-Net packet and retrieve the opcode that
       tells what kind of message it is                         */
    int opcode = artNetOpCode(packetBuffer);
    if (opcode == ARTNET_ARTDMX) {
    
      artDMXReceived(packetBuffer);
      currentcounter++;                //increase counter by 1 each time through
      digitalWrite(STATUS_LED, HIGH);  //turn status LED on
    }
  }

EthernetClient client = server.available();  // try to get client

  if (client) {  // got client?
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {  // client data available to read
        char c = client.read();  // read 1 byte (character) from client
        // buffer first part of HTTP request in HTTP_req array (string)
        // leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1)
        if (req_index < (REQ_BUF_SZ - 1)) {
          HTTP_req[req_index] = c;  // save HTTP request character
          req_index++;
        }
        // last line of client request is blank and ends with \n
        // respond to client only after last line received
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          // remainder of header follows below, depending on if
          // web page or XML page is requested
          // Ajax request - send XML file
          if (StrContains(HTTP_req, "ajax_inputs")) {
            // send rest of HTTP header
            client.println("Content-Type: text/xml");
            client.println("Connection: keep-alive");
            client.println();
            // send XML file containing input states
            XML_response(client);
          } else {  // web page request
            // send rest of HTTP header
            client.println("Content-Type: text/html");
            client.println("Connection: keep-alive");
            client.println();
            // send web page
            webFile = SD.open("index.htm");  // open web page file
            if (webFile) {
              while (webFile.available()) {
                client.write(webFile.read());  // send web page to client
              }
              webFile.close();
            }
          }
          // display received HTTP request on serial port
          Serial.print(HTTP_req);
          // reset buffer index and all buffer elements to 0
          req_index = 0;
          StrClear(HTTP_req, REQ_BUF_SZ);
          break;
        }
        // every line of text received from the client ends with \r\n
        if (c == '\n') {
          // last character on line of received text
          // starting new line with next character read
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // a text character was received from client
          currentLineIsBlank = false;
        }
      }             // end if (client.available())
    }               // end while (client.connected())
    delay(1);       // give the web browser time to receive the data
    client.stop();  // close the connection
  }                 // end if (client)
}

// send the XML file containing analog value
void XML_response(EthernetClient cl) {
int analog_val;
double celsius = thermocouple.readCelsius(); 
double fahrenheit = thermocouple.readFahrenheit();
int pressure = analogRead(pressureSensorPin);  // Read the pressure sensor
pressure = map(pressure, 0, 1023, 0, 250);     // Map the reading to PSI
int flowRate = pulseIn(flowSensor, HIGH);
int SW;
        
  cl.print("<?xml version = \"1.0\" ?>");
  cl.print("<inputs>");
  //Fuel Pump int
  cl.print("<SW>");
    if (digitalRead(22)) {
        cl.print("unchecked");
    }
    else {
        cl.print("checked");
    }
    cl.print("</SW>");
     //Nitrogen Val int
  cl.print("<SW>");
    if (digitalRead(24)) {
        cl.print("unchecked");
    }
    else {
        cl.print("checked");
    }
    cl.print("</SW>");
     //Pilot Lite Val int
  cl.print("<SW>");
    if (digitalRead(26)) {
        cl.print("unchecked");
    }
    else {
        cl.print("checked");
    }
    cl.print("</SW>");
     //Firing Val int
  cl.print("<SW>");
    if (digitalRead(28)) {
        cl.print("unchecked");
    }
    else {
        cl.print("checked");
    }
    cl.print("</SW>");
    //read fuel into tank
  analog_val = flowMilliLiters += (flowRate / (60 * 7.5));
  cl.print("<analog>");
  cl.print(analog_val);
  cl.print("</analog>");
  analog_val = (fahrenheit);
  cl.print("<analog>");
  cl.print(analog_val);
  cl.print("</analog>");
  analog_val = (pressure);
  cl.print("<analog>");
  cl.print(analog_val);
  cl.print("</analog>");
  analog_val = (A9);
  cl.print("<analog>");
  cl.print(analog_val);
  cl.print("</analog>");
  analog_val = (A10);
  cl.print("<analog>");
  cl.print(analog_val);
  cl.print("</analog>");
  cl.print("</inputs>");
}

// sets every element of str to 0 (clears array)
void StrClear(char* str, char length) {
  for (int i = 0; i < length; i++) {
    str[i] = 0;
  }
}

// searches for the string sfind in the string str
// returns 1 if string found
// returns 0 if string not found
char StrContains(char* str, char* sfind) {
  char found = 0;
  char index = 0;
  char len;

  len = strlen(str);

  if (strlen(sfind) > len) {
    return 0;
  }
  while (index < len) {
    if (str[index] == sfind[found]) {
      found++;
      if (strlen(sfind) == found) {
        return 1;
      }
    } else {
      found = 0;
    }
    index++;
  }
  return 0;
}



//End loop

What's that for?

Nothing on a computer happens with no delay at all. On a 18MHz AVR, the fastest possible operation takes one machine cycle, 1/16 of a microsecond.

Please provide specific timing requirements.

That's probably not a good idea.

Review the return statement and what it does.

To make that code go way faster, remove any calls to delay().

a7

I need this section of code to run instantly, if not familiar with artnet think of these two lines of code as push button switches

if (pbuff[ARTNET_START_ADDRESS + channel1] == 200)

if (pbuff[ARTNET_START_ADDRESS + channel2] == 200)

Channel 1 run fine but channel 2 currently after it is enabled by the controller takes 4 seconds to turn on the relay. In this code there is no delays until channel two is enabled.

void artDMXReceived(unsigned char* pbuff) {
  ms_from_start   = millis();
  if ((pbuff[14] & 0xF) == ARTNET_UNIVERSE) {
    if ((pbuff[14] >> 8) == ARTNET_SUBNET) {
     if (pbuff[ARTNET_START_ADDRESS + channel1] == 200)  //if channel value is 200
     {
        flowRate = pulseIn(flowSensor, HIGH);        // Read the flow rate
        flowMilliLiters += (flowRate / (60 * 7.5));  // Calculate the cumulative amount of fluid

        if (flowMilliLiters >= fuelVolume) {  // If the cumulative amount of fluid is greater than or equal to 1000 ml
          digitalWrite(pumpPin, HIGH);        // Turn off the relay
        } else {                              // If the cumulative amount of fluid is greater than or equal to 1000 ml
          digitalWrite(pumpPin, LOW);         // Turn off the relay
         }
        {
          
          if (flowMilliLiters >= fuelVolume) {
            digitalWrite(pilotPin, LOW);
          }
          int pressure = analogRead(pressureSensorPin);  // Read the pressure sensor
          pressure = map(pressure, 0, 1023, 0, 250);     // Map the reading to PSI
          if (flowMilliLiters >= fuelVolume) {
            digitalWrite(nitrogenPin, LOW);  // Keep the relay on
          }
          {
            if (pressure >= thresholdPressure) {  // If pressure is above threshold
            
              digitalWrite(nitrogenPin, HIGH);    // Turn off the relay
           }
          }
         }
        }
      } else {
           digitalWrite(pumpPin, HIGH);
            digitalWrite(nitrogenPin, HIGH);
            digitalWrite(pilotPin, HIGH);
      }
      double fahrenheit = thermocouple.readFahrenheit();
      double celsius = thermocouple.readCelsius();  
          int pressure = analogRead(pressureSensorPin);  // Read the pressure sensor
          pressure = map(pressure, 0, 1023, 0, 250);     // Map the reading to PSI      
         if (pbuff[ARTNET_START_ADDRESS + channel2] == 200 && pressure >= thresholdPressure && flowMilliLiters >= fuelVolume && fahrenheit > pilotTemp) {
            digitalWrite(firePin, LOW);  //Fire
            Serial.println("FIRING!!!!!!!!");
            delay(10000);
            digitalWrite(firePin, HIGH);
            digitalWrite(pumpPin, HIGH);
            digitalWrite(nitrogenPin, HIGH);
            digitalWrite(pilotPin, HIGH);
            (flowMilliLiters = 0);
            return (setup());
    }
  }
} 
 //end artDMXReceived

Post a link, as suggested in the forum guidelines.

What is that supposed to do?

Already covered...

Where has it been covered?

My guess - OP believes it will direct program flow to setup().

In other words, taking wild guesses at C/C++ language syntax.

Post 2.
Do at least try to keep up

The OP has not addressed the question in post#2 or post#4 or post#7.

They're probably overwhelmed

duplicate thread
https://forum.arduino.cc/t/issue-with-timing-with-artnet-2-channels-of-artnet/1093246/4

return (setup());. this was put in because after Artnet channel 2 ran its program alway the pumpPin relay would turn on for at least 2-4 seconds until it got down to the else to turn the pump high again. for this project it could not do that so I sent the return all the way back to the top to the setup function and that fixed the problem.

That is not even close to how you would do that in C. When you program in a language, you can't just invent syntax. You have to learn the rules of the language.

Didn't you get a compiler warning about returning the value a void function doesn't return?

Warnings are often disabled by default.

Would that be recursion?

I have deleted your duplicate post in the other topic @krsentertainment.

In the future, please only create one topic for each distinct subject matter and be careful not to cause them to converge into parallel discussions. For now, I think the two topics are distinct from each other so I don't see the need to merge them. Please keep it that way.

The reason is that generating multiple threads on the same subject matter can waste the time of the people trying to help. Someone might spend a lot of time investigating and writing a detailed answer on one topic, without knowing that someone else already did the same in the other topic.

Thanks in advance for your cooperation.


There is some valuable advice in the other topic that is applicable to most projects and problems, including this one: