Arduino taking a Long time till it activates

Im not kompletly sure if this is the right place to post this, if it’s not, please tell me were to post it. :smiley:

I am currently writing a program that will communicate with an arduino. My problem is that the time between starting the program on my PC and running the setup function on the arduino is quite long (10-20 sec). There is allso a 10second delay between giving the arduino Power through the USB Port and the arduino executing the setup funktion. This is not a big problem for me, but it would be nicer if the Arduino would not take so long.

I am using an Arduino Mega 2560 from Funduino, had no problem with it since now.

Here’s my Java code:

package core;

import java.io.PrintWriter;
import java.util.Scanner;

import com.fazecast.jSerialComm.SerialPort;

public class ArduinoController extends Thread {

    private Main main;                //The Instance of the core.Main class
    private Scanner data;               //A scanner that is used for recieving Messages from the Arduino
    private SerialPort port;            //The Port for communication with the Arduino
    private PrintWriter printWriter;    //For sending Messages to the Arduino
    private boolean setupComplete;      //True when the Arduino has Calibrated his Fades, and listens for Messages
    private boolean arduinoConnected;   //False, when the Serial Port couldn't be established, normaly if the Arduino is not Connected, or if a nother Programm is connected to it

    public ArduinoController(SerialPort pPort, Main main) {
        this.main = main;

        port = pPort;
        if (port.openPort()) {
            System.out.println("Arduino: Successfully opened the port.");
            arduinoConnected = true;
            port.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 0, 0);
            port.setBaudRate(1000000);
            printWriter = new PrintWriter(port.getOutputStream());
            data = new Scanner(port.getInputStream());
            start();
        } else {
            System.out.println("Arduino: Unable to open the port.");
            arduinoConnected = false;
            return;
        }
    }

    @Override
    public void run() {
        super.run();
        while (data.hasNextLine()) {
            String serialMessage = data.nextLine();
            if (serialMessage.equals("S;E")) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sendAllValues();
            }
            MessageFromArduino decodedMessage = new MessageFromArduino(serialMessage);
            if (decodedMessage.msgComplete) {
                if (1 == decodedMessage.commandType) {
                    try {
                        main.faders[decodedMessage.sensorID].setValue(main.getActivePhysicalFaderpage(), decodedMessage.sensorValue, true, false);
                    } catch (NullPointerException e){
                        e.printStackTrace();
                    }
                    decodedMessage.used = true;
                }

                if (!decodedMessage.used)
                    System.out.println("ERROR: unused Message: \"" + serialMessage + "\"");
            }
        }
    }

    public void sendAllValues() {
        for (int i = 0; i < main.getPhysicalFaderAmount(); i++) {
            sendMessage(new MessageToArduino(i, main.faders[i].values[main.getActivePhysicalFaderpage()][0]), true); //faderController.faders[i].valuePages[master.activeFaderPage]
        }
    }

    public void sendMessage(MessageToArduino msg, boolean sendCommandlineFeedback) {
        if (this.arduinoConnected) {
            printWriter.print(msg.getString());
            printWriter.flush();
            if (sendCommandlineFeedback) System.out.println("Send Message: " + msg.getString());
        } else {
            System.out.println("Cant send Message: Not Connected (" + msg.getString() + ")");
        }

    }

    public void shutdown() {
        this.port.closePort();
    }

    public class MessageFromArduino {

        public int addresseeID; //ID of the Device the Msg is send to
        public int commandType; //what the command does (0 for msg without real content, used to mark the end of a loop at the Arduino or a successfully received msg, 1 for getValue, 2 for setValue (for Motorfaders))
        public int sensorType; //what type of Sensor is effected
        public int sensorID; //which sensor was effected
        public int sensorValue; //what the new value of the sensor is
        public int furtherInformation; //for a potentiometer e.g. the exact value
        public boolean msgComplete; //whether the message was complete
        public boolean used;

        public MessageFromArduino(String msg) {
            String[] args = msg.split(";");
            this.msgComplete = args.length == 8 && "S".equals(args[0]) && "E".equals(args[7]);
            if (this.msgComplete) {
                this.addresseeID = Integer.parseInt(args[1]);
                this.commandType = Integer.parseInt(args[2]);
                this.sensorType = Integer.parseInt(args[3]);
                this.sensorID = Integer.parseInt(args[4]);
                this.sensorValue = Integer.parseInt(args[5]);
                this.furtherInformation = Integer.parseInt(args[6]);
            }
            used = false;
        }
    }

    public static class MessageToArduino {

        public int sensorID; //which sensor was effected
        public int sensorValue; //what the new value of the sensor is
        public boolean msgComplete; //whether the message was complete

        public MessageToArduino(int sensorID, int sensorValue) {
            this.sensorID = sensorID;
            this.sensorValue = sensorValue;
        }

        public MessageToArduino(String msg) {
            String[] args = msg.split(";");
            this.msgComplete = args.length == 8 && "S".equals(args[0]) && "E".equals(args[7]);
            if (this.msgComplete) {
                this.sensorID = Integer.parseInt(args[0]);
                this.sensorValue = Integer.parseInt(args[1]);
            }
        }

        public String getString() {
            return "S;" + this.sensorID + ";" + this.sensorValue + ";E";
        }
    }
}

Because this post would otherwise be too long, I posted my Arduino code under the following link:

Please attach your Arduino code as an attachment.

The Mega's boot loader takes a bit of time, but that should be around 5 seconds.

In your Java code, you can open the serial port without activating the DTR line; that will prevent the boot loader from being activated. Do a little research.

Your Arduino code; fitted in a separate post :slight_smile:

int numberOfPotis = 2;
int numberOfButtons = 5;
int potiValues[2] = {0, 0};
int highLowValues[2][2] = {{1023, 0}, {1023, 0}};

void setup() {
  Serial.begin(1000000);

  for (int i = 0; i < numberOfPotis; i++) {
    analogWrite(i + 2, 255);
    setPhysicalFaderValueToFull (i);
    highLowValues[i][1] = analogRead(i);
    setPhysicalFaderValueToNull (i);
    highLowValues[i][0] = analogRead(i);
  }
  Serial.println("S;E");
}

void loop() {
  if (Serial.available() > 0 && char(Serial.read()) == 'S') {
    readMsg();
  }
  int newValue;
  for (int i = 0; i < numberOfPotis; i++)
  {
    newValue = readPoti(i);
    if (newValue != potiValues[i]) {
      potiValues[i] = newValue;
      String line;
      line =  "S;0;1;" + String(1) + ";" + String(i) + ";" + String(potiValues[i]) + ";" +  String(newValue) + ";E"; //System: S;commandType(1=getValue);valueType;sensorID;value;debugInfo;E
      Serial.println(line);
    }
  }
}

void setPhysicalFaderValueToNull (int faderID) {
  int upPin = 22 + (2 * faderID);
  int downPin = upPin + 1;
  digitalWrite(downPin, HIGH);
  digitalWrite(upPin, LOW);
  delay(500);
  digitalWrite(downPin, LOW);
}

void setPhysicalFaderValueToFull (int faderID) {
  int upPin = 22 + (2 * faderID);
  int downPin = upPin + 1;
  digitalWrite(upPin, HIGH);
  digitalWrite(downPin, LOW);
  delay(500);
  digitalWrite(upPin, LOW);
}

void setMotorPoti(int faderID, int value) {
  int upPin = 22 + (faderID * 2);
  int downPin = upPin + 1;
  int speed1 = 140;
  int speed2 = 110;
  int range = 5;

  while (readPoti(faderID) != value) {
    analogWrite(faderID + 2, speed1);
    while (getPositiveInt(value - readPoti(faderID))>range) {
      int potiValue = readPoti(faderID);
      if (potiValue < value) {
        digitalWrite(upPin, HIGH);
        digitalWrite(downPin, LOW);
      }

      if (potiValue > value) {
        digitalWrite(upPin, LOW);
        digitalWrite(downPin, HIGH);
      }
      Serial.println("High");
    }

    analogWrite(faderID + 2, 255);
    while (readPoti(faderID) != value) {
      int potiValue = readPoti(faderID);
      analogWrite(faderID + 2, map(getPositiveInt(value - potiValue), 0, 100, speed2, 255) * 1);
      if (potiValue < value) {
        digitalWrite(upPin, HIGH);
        digitalWrite(downPin, LOW);
      }

      if (potiValue > value) {
        digitalWrite(upPin, LOW);
        digitalWrite(downPin, HIGH);
      }
      Serial.print("LOW: ");
      Serial.println(potiValue);
    }
    digitalWrite(upPin, LOW);
    digitalWrite(downPin, LOW);
    if (readPoti(faderID) != value) delay(100);
  }
  potiValues[faderID] = value;
}

void readMsg() {
  boolean msgComplete = false;
  int msgValues[2] = {0, 0};
  int activeSlot = -1;
  while (Serial.available() > 0) {
    char nextChar = char(Serial.read());
    switch (nextChar) {
      case 'E':
        msgComplete = true;
        break;
      case ';':
        activeSlot++;
        break;
      default:
        msgValues[activeSlot] = (msgValues[activeSlot] * 10) + (nextChar - '0');
        break;
    }
    if (nextChar == 'E') {
      break;
    }
  }
  if (msgValues[0] < numberOfPotis && msgValues[1] <= 100) {
    //    while (readPoti(msgValues[0]) != msgValues[1]) {
    setMotorPoti(msgValues[0], msgValues[1]);
    //      delay(10);
    //    }
  }
}

int readPoti(int pin) {
  int iterations = 30;
  int gesammt = 0;
  for (int i = 0; i < iterations; i++) {
    gesammt += analogRead(pin);
  }
  return map(gesammt / iterations, highLowValues[pin][1], highLowValues[pin][0] - 1, 100, 0);
}

int getPositiveInt (int i) {
  if (i < 0) i = i * -1;
  return i;
}

FYI, you have have created an additional 2 seconds delay in setup() ;) More potis and more delay ;)

You're advised not to use String (capital S) on an Arduino; it can make a swiss cheese if you memory resulting in undefined behaviour at run time. It will probably not happen with your current code but significant use of specifically String concatenation in more complicated programs will eventually bite you.

Forget that String exists !!

sterretje: Forget that String exists !!

What should I use instead?

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

For my programs that communicate with a PC I get the Arduino to send a message such as "Arduino is ready" from setup() and make the PC program wait for that before it tries to send anything to the Arduino. In general the startup time is a few seconds - certainly not 20 seconds. This Simple Python - Arduino demo illustrates the idea.

...R

Robin2: For my programs that communicate with a PC I get the Arduino to send a message such as "Arduino is ready" from setup() and make the PC program wait for that before it tries to send anything to the Arduino. In general the startup time is a few seconds - certainly not 20 seconds. This Simple Python - Arduino demo illustrates the idea.

...R

I did that, my Message is "S;E" but its the same Idea, as I sead its noc a big Problem, its just something i would like to get rid of

isi_ko: I did that, my Message is "S;E" but its the same Idea, as I sead its noc a big Problem, its just something i would like to get rid of

I'm not clear what it is you want to get rid of?

If you want to communicate with an Arduino without the opening of the serial connection causing the Arduino to reset then a simple way is to use a USB-TTL cable connected directly to Rx Tx and GND rather than the regular USB connection.

...R

Robin2: I'm not clear what it is you want to get rid of?

I what to get rid of the long delay, between starting the Programm and the Arduino executing th setup funktion

See reply #1; modify your java code; that will save you the bulk of the time.

I'm not a java programmer but the jSerial library seems to have methods for it if I look at the library source code. Use the function that you find before opening the serial port.