Information sending from Java to Arduino

Hi!
I want to send data from a Java program on my PC to an Arduino. I can send data to both direction, but I have some trouble with data sending to Arduino - sent data is incorrect.
Arduino code:

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available () > 0) {
    int solution = Serial.read();
    if (solution == 1) {
      soundVolumeVolt();
    }
    else if (solution == 2) {
      FFTsound();
    }
    delay(100);
  }
}
void FFTsound() {
  /*SAMPLING*/
  microseconds = micros();
  for (int i = 0; i < samples; i++)
  {
    vReal[i] = analogReadFast(CHANNEL);
    vImag[i] = 0;
    while (micros() - microseconds < sampling_period_us) {
      //empty loop
    }
    microseconds += sampling_period_us;
  }
  /* Print the results of the sampling according to time */
  //   Serial.println("Data:");
  //   PrintVector(vReal, samples, SCL_TIME);
  FFT.Windowing(vReal, samples, FFT_WIN_TYP_HAMMING, FFT_FORWARD);  /* Weigh data */
  //   Serial.println("Weighed data:");
  //   PrintVector(vReal, samples, SCL_TIME);
  FFT.Compute(vReal, vImag, samples, FFT_FORWARD); /* Compute FFT */
  //   Serial.println("Computed Real values:");
  //   PrintVector(vReal, samples, SCL_INDEX);
  //   Serial.println("Computed Imaginary values:");
  //   PrintVector(vImag, samples, SCL_INDEX);
  FFT.ComplexToMagnitude(vReal, vImag, samples); /* Compute magnitudes */
  // Serial.println("Computed magnitudes:");
  PrintVector(vReal, (samples >> 1), SCL_FREQUENCY);
  double x = FFT.MajorPeak(vReal, samples, samplingFrequency);
  // Serial.println(x, 6); //Print out what frequency is the most dominant.
  //  while(1); /* Run Once */
  delay(2000); /* Repeat after delay */
}

// changing the register value of prescaler, for increase max samplingFreq, you can use it instead of analogRead
int analogReadFast(int CHANNEL) {
  byte ADCregOriginal = ADC0_CTRLC;
  ADC0_CTRLC = 0x54; // reduced cap, Vdd ref, 32 prescaler. See page 408 in the datasheet to change register value
  int adc = analogRead(CHANNEL);
  ADC0_CTRLC = ADCregOriginal;
  return adc;
}

void PrintVector(double *vData, uint16_t bufferSize, uint8_t scaleType)
{
  double numbers[16];
  for (uint16_t i = 0; i < bufferSize; i++)
  {
    double abscissa;
    /* Print abscissa value */
    switch (scaleType)
    {
      case SCL_INDEX:
        abscissa = (i * 1.0);
        break;
      case SCL_TIME:
        abscissa = ((i * 1.0) / samplingFrequency);
        break;
      case SCL_FREQUENCY:
        abscissa = ((i * 1.0 * samplingFrequency) / samples);
        break;
    }
    //  Serial.print(abscissa, 6);
    if (scaleType == SCL_FREQUENCY)
      //   Serial.print("Hz");
      numbers[i] = {vData[i]}; //save calcuated magnnitudes data to array
    doc["Harmonic"][i] = numbers[i]; // creating json based on array
    //   Serial.print(" ");
    //   Serial.println(vData[i], 4);
  }
  serializeJson(doc, Serial);
  Serial.println();
}

void soundVolumeVolt() {
  unsigned long startMillis = millis();
  unsigned int peakToPeak = 0;   

  unsigned int signalMax = 0;
  unsigned int signalMin = 1024;

  while (millis() - startMillis < sampleWindow)
  {
    sample = analogReadFast(CHANNEL);
    if (sample < 1024)
    {
      if (sample > signalMax)
      {
        signalMax = sample; 
      }
      else if (sample < signalMin)
      {
        signalMin = sample; 
      }
    }
  }
  peakToPeak = signalMax - signalMin;  
  Serial.println(peakToPeak);
}

Java code:

 package IRSend;

import com.fazecast.jSerialComm.SerialPort;

import java.io.*;

import com.google.common.collect.Lists;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.android.nativekey.AndroidKey;
import io.appium.java_client.android.nativekey.KeyEvent;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.remote.DesiredCapabilities;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.concurrent.TimeUnit;
import org.json.*;

public class lkj {
    private static SerialPort chosenPort;
    private static BufferedReader input;
    static AndroidDriver<AndroidElement> driver;
    static Map< String, Object > driver_args = new HashMap< >();
    static List <AndroidElement> elements;

    public static void main(String[] args) {
        chosenPort = SerialPort.getCommPort("COM3");
        chosenPort.openPort();
        chosenPort.setBaudRate(9600);
        chosenPort.setComPortTimeouts(SerialPort.TIMEOUT_SCANNER, 0, 0);
        try {
            connect();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        // Initialize report
        List<String> report = new ArrayList<>();
        report.add("ENG LOCAL:\n");
        jserialInputPreset();
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        jserialOutputPreset();
        chosenPort.closePort();
    }

    private static void jserialInputEqual(){
        OutputStream output = chosenPort.getOutputStream();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
        try {
            output.write(1);
            output.flush();
            Thread.sleep(100);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
    }
    private static void jserialInputPreset(){
        OutputStream output = chosenPort.getOutputStream();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
        try {
            output.write(2);
            output.flush();
            Thread.sleep(100);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
        }

    private static void jserialOutputPreset() {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
        String arduino = null;
        try {
            input = new BufferedReader(new InputStreamReader(chosenPort.getInputStream()));
            arduino = input.readLine();
            Thread.sleep(100);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
        System.out.println(arduino);
    }

    private static void dpad(AndroidKey key) {
        driver.pressKey(new KeyEvent(key));
    }

    private static MobileElement findElementByImage(String using) {
        try {
            return driver.findElementByImage(using);
        } catch (NoSuchElementException e) {
            return null;
        }
    }

    private static AndroidElement findElementWrapper(String using) {
        try {
            return driver.findElement(By.id(using));
        } catch (NoSuchElementException e) {
            return null;
        }
    }

    private static AndroidElement findElementByXPathWrapper(String using) {
        try {
            return driver.findElementByXPath(using);
        } catch (NoSuchElementException e) {
            return null;
        }
    }

    public static void connect() throws MalformedURLException {
        DesiredCapabilities dc = new DesiredCapabilities();
        dc.setCapability("deviceName", "komagome");
        dc.setCapability("noReset", "true");
        dc.setCapability("platformName", "Android");
        dc.setCapability("platformVersion", "9");
        URL url = new URL("http://127.0.0.1:4723/wd/hub");
        driver = new AndroidDriver < AndroidElement > (url, dc);
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);

        System.out.println("Application started....");
    }
}


The logic of the code is simple - Java sends the number (int), Arduino receive it and fulfills the condition. But the condition was never met. This is hard to debug because I can’t open the serial monitor of the Arduino when I’m communicating with my Java program. So I added Serial.println(solution). If I enter 1 in Arduino terminal, that shows 49, if I enter 1 via Java output.write(1);and receive it, Java terminal shows 1. I know, that Serial.read() takes on values in ASCII, so I tried method Serial.parseInt(), but it doesn't work either.
I think the problem is in Java code, but I can't detect it. I have been doing programming not so long ago, so please describe your answers in detail. I checked similar topic and there was problem in end marker, but I don't know how to create it.
Thanks in advance!

I do not know what Java sends. I know nothing of that language.

If you are receiving ASCII for 1 then use '1' in your if.

if (solution == '1')

I tried this method, but it does not work(
Thank you.

my understanding is the above reads a single byte, but your java code may be sending an int, 4 bytes. but intel processors are little-endian, so should send the LSB first

you have a 100 ms delay. why?

and how is the serial bit rate set/determine in the java code? is it 9600?

Instead of

try

output.println("2"); 

instead that will send 2 as text with a new line following (avoids BigEndian/LittleEndian problems)
Then in the Arduino
try

String input;

void soundVolumeVolt() {
  Serial.println(F("soundVolumeVolt"));
}
void FFTsound() {
  Serial.println(F("FFTsound"));
}

String input;
void loop() {
  input = Serial.readStringUntil('\n'); // block here for 1sec each loop looking for input
  // if nothing will return empty input
  input.trim(); //remove and \r and leading/trailing white space
  if (input.length() > 0) { // got something
    if (input == "1") {
      soundVolumeVolt();
    } else if (input == "2") {
      FFTsound();
    } else {
      Serial.println(F("Invalid"));
      // invalid input ignore
      // flash led??
    }
  }
}

For debugging try just writing back to the Serial and picking it up in the Java

1 Like

Delay is a habit for me, because sometimes Arduino slow down from the loop, we can delete the delay in this case.
Initialization of serial port in java

        chosenPort = SerialPort.getCommPort("COM3");
        chosenPort.openPort();
        chosenPort.setBaudRate(9600);
        chosenPort.setComPortTimeouts(SerialPort.TIMEOUT_SCANNER, 0, 0);

OutputStream class hasn't prinln method, only bitwise data transfer, but i tried to use symbol class PrintWritter in Java, and Serial.parseInt() in Arduino. it's work!
Java code:

    private static void jserialInputPreset(){
        PrintWriter outArduino = new PrintWriter(chosenPort.getOutputStream());
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
        outArduino.print(2);
        outArduino.flush();
        }

Arduino code:

void loop()
{
  if (Serial.available () > 0) {
    int solution = Serial.parseInt();
    if (solution == 1) {
      soundVolumeVolt();
    }
    else if (solution == 2) {
      FFTsound();
    }
    else {
      Serial.println("loh");
    }
    delay(100);
  }
}

Thanks all!