Arduino to Java data sending

I'm reciving data from a transductor on a PCB that sends a number to my Arduino Due's SPI bus and then I want to send this data to a Java program for processing the data.


#include <SPI.h>
#include "Wire.h"
#include <LCD_I2C.h>

LCD_I2C lcd(0x27, 16, 2);

float valorRetorno60;
float valorRetorno41;
float valorRetorno00;

void setup() 
{
  pinMode(SS, OUTPUT);
  pinMode(50, OUTPUT);
  pinMode(52, OUTPUT);
  pinMode(24, OUTPUT);
  Serial.begin(115200);
  SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
  //HSSI tiene un reloj de 10MHz
  SPI.begin();
  lcd.begin();
  lcd.backlight();
}

void loop() 
{
  digitalWrite(50, HIGH);
  digitalWrite(50,LOW);

  valorRetorno60 = SPI.transfer(0x60);
  valorRetorno41 = SPI.transfer(0x41);

  digitalWrite(52, HIGH);
  digitalWrite(52, LOW);


  valorRetorno00 = SPI.transfer16(0x00)>>4;
  Serial.println(valorRetorno00);
  digitalWrite(24, HIGH);
  digitalWrite(24, LOW);
}

That's my code at the moment, I'll later add more for the Java to Arduino coms, but that's not something that I need for now

Is there any library, method, or something I can do? I just saw an UART to USB convertor that I could connect to Arduino and then to Java, but that would be more code, wait for that to arrive and I wanted to know if there's any form I can already use the USB port the Arduino is using

Thanks

There where multiple solutions. UART=>USB but only works if the java program is opened.

Put the data in a database en take it with the java program and sql query's. That's the way I prefer.

1 Like

the simplest way is

  1. your program writes the sensor data to Serial where it would appear on the Arduino IDE Serial Monitor
  2. close the Serial Monitor
  3. run your java program which opens the COM port associated with the Arduino device, reads the serial data and processes it

when you wish to program the Ardunio again you wioll need to close the Java program (or at least close the serial port)

an alternative is to use a USB-TTL serial dongle and connect it to a Arduino Serial port (preferably hardware) - your java program connects to the COM port associated with the USB-TTL dongle

for Java serial example have a look at Java terminal emulator

Edit: if you device has WiFi (e.g. ESP32, ESP8266, etc) your Java program could run a TCP or UDP server and the ESP runs a client which transmits sensor data to it

simple example - Arduino program transmitting a float every 5 seconds

// loop transmitting a float value to serial monitor evry 5 seconds

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

void loop() {
  static long timer = millis();
  static float test = 3.14159f;
  // if keyboard hit echo character
  if (Serial.available())
    Serial.print((char)Serial.read());
  // every 5 seconds transmit a float
  if (millis() - timer > 5000) {
    timer = millis();
    Serial.println(test);
    test += 2.5;
  }
}

serial monitor displays

3.14
5.64
8.14
10.64
13.14
15.64

close serial monitor
run following Java program which reads a line of text and attempts to parse a float value

// ConsoleTerminal.java: read keyboard and transmit to COM port - read any response
//
// note requires jSerialComm jar file from https://fazecast.github.io/jSerialComm/

// compile and run commands - note that jSerialComm file should be in same directory as java source file
// javac -cp .\jSerialComm-2.9.3.jar;.  ConsoleTerminal.java
// java -cp .\jSerialComm-2.9.3.jar;.  ConsoleTerminal

import com.fazecast.jSerialComm.*;
import java.util.*;
public class ConsoleTerminal {
    private static SerialPort comPorts[];
    private static int port=-1;
    public static SerialPort comPort;
    public static StringBuilder text=new StringBuilder();  // will hiold a line of text to be parse for an float

    public static void main(String[] args) { 
        Scanner console = new Scanner(System.in);
        System.out.println("List COM ports");
        // read list of COM ports and display them
        comPorts = SerialPort.getCommPorts();
        if(comPorts.length<1)           // if no COM ports found exit
            {System.out.println("no COM ports found"); return;}
        // print list of COM ports, add to COMportMenu and attach event handler
        for (int i = 0; i < comPorts.length; i++)   { 
           System.out.println("comPort[" + i + "] = " + comPorts[i].getDescriptivePortName());
                }
       if(comPorts.length==1)            // if 1 COM port found open it
            {port=0; openCOMport();}
       else
       {
           System.out.print("\nEnter COM port (0, 1, 2 etc) to select serial port ");
           if(console.hasNextInt()) {
             port = console.nextInt(); 
             openCOMport();
           }
       }
       // loop read characters from keyboard transmit over serial
       //   read characters from serial and display them
       try {
         while (true)
         {
           // if keyboard token entered read it
           if(System.in.available() > 0)
           {
             //System.out.println("enter chars ");
             String s = console.nextLine() + "\n";                       // read text
             byte[] writeBuffer=s.getBytes() ;
             comPorts[port].writeBytes(writeBuffer, writeBuffer.length); // transmit it
             //System.out.println("write " + writeBuffer.length);
           }
           // read serial port  and display data
           if(comPort.bytesAvailable() > 0) 
           {
             byte[] data = new byte[10];
             comPort.readBytes(data,1);
             System.out.print((char)data[0]);
             if((char)data[0] >= ' ') 
               text.append((char)data[0]);  // if printable append to text
             else 
               // ****  if end of line parse text for a float value  ****
               if((char)data[0]== '\n'){
                  System.out.println("new text array " + text);
                  float x = Float.parseFloat(text.toString());
                  System.out.println("*** float value parsed " + x);
                  text.setLength(0);
             }
          }


         }
       } catch (Exception e) { e.printStackTrace(); }
       comPorts[port].closePort();         
   }
  
    // attempt to open COM port 
    static void openCOMport() {
        comPort = SerialPort.getCommPorts()[port];
        System.out.println("attempting to open " +  comPorts[port].getDescriptivePortName() + "\n");
        if(!comPort.openPort()) 
           { System.out.println("failed to open COM port " + comPorts[port].getDescriptivePortName() + "\n"); port=-1; return; }
        System.out.println("Opened COM port " + comPorts[port].getDescriptivePortName() + " OK\n");
        comPort.setBaudRate(115200);
        }        
}

when run using Windows command prompt displays (the Arduino UNO is on COM23)

F:\temp>java -cp .\jSerialComm-2.9.3.jar;.  ConsoleTerminal
List COM ports
comPort[0] = Silicon Labs CP210x USB to UART Bridge (COM18)
comPort[1] = USB Serial Port (COM22)
comPort[2] = USB Serial Device (COM21)
comPort[3] = Communications Port (COM1)
comPort[4] = USB-SERIAL CH340 (COM23)
comPort[5] = Intel(R) Active Management Technology - SOL (COM13)

Enter COM port (0, 1, 2 etc) to select serial port 4
attempting to open USB-SERIAL CH340 (COM23)

Opened COM port USB-SERIAL CH340 (COM23) OK

3.14
new text array 3.14
*** float value parsed 3.14
5.64
new text array 5.64
*** float value parsed 5.64
8.14
new text array 8.14
*** float value parsed 8.14
10.64
new text array 10.64
*** float value parsed 10.64
13.14
new text array 13.14
*** float value parsed 13.14
15.64
new text array 15.64
*** float value parsed 15.64
18.14
new text array 18.14
*** float value parsed 18.14
20.64
new text array 20.64
*** float value parsed 20.64
23.14
new text array 23.14
*** float value parsed 23.14
25.64
new text array 25.64
*** float value parsed 25.64
28.14
new text array 28.14
*** float value parsed 28.14

the Java program requires the jSerialComm jar file

1 Like

That was so useful, I'm so close to get it right thanks to you :smile:
I get an error from another library called XChart that graphs the data I'm getting from Arduino that doesn't "cut" the data into strings.

import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

import javax.swing.SwingWorker;

import org.knowm.xchart.QuickChart;
import org.knowm.xchart.SwingWrapper;
import org.knowm.xchart.XYChart;

import com.fazecast.jSerialComm.*;

public class ConsoleAndGraphGen
{
    // Declaración de métodos y clases a ocupar
    GraficaDeDatosAvea graficaAvea1;
    SwingWrapper<XYChart> datos;
    XYChart grafica;
    Scanner entradaPuertos = new Scanner(System.in);
    private static SerialPort comPorts[];
    private static int port=-1;
    public static SerialPort comPort;
    public static StringBuilder text=new StringBuilder();

    public static void main(String[] args)
    {
        // Ejecución del programa
        ConsoleAndGraphGen entradaDatos = new ConsoleAndGraphGen();
        entradaDatos.goF();
    }

    private void goF()
    {
        // Configuración de la gráfica y apertura de puertos USB
        grafica = QuickChart.getChart("Datos", "Tiempo", "Flujo de datos", "Arduino Coms", new double[]{0}, new double[]{0});
        grafica.getStyler().setLegendVisible(false);
        grafica.getStyler().setXAxisTicksVisible(false);

        System.out.println("Lista de puertos COM");
        comPorts = SerialPort.getCommPorts();
        if(comPorts.length > 1)
        {
            System.out.println("No se encontraron puertos disponibles");
        }
        for(int i = 0; i < comPorts.length; i++)
        {
            System.out.println("Puerto COM[" + i +"] = " + comPorts[i]);
        }
        if(comPorts.length == 1)
        {
            port = 0;
            openCOMport();
        }
        else
        {
            System.out.println("\n\nIngrese el puerto a enlazar previo a graficar los datos de presión:");
            if(entradaPuertos.hasNextInt())
            {
                port = entradaPuertos.nextInt();
                openCOMport();
            }
        }

        datos = new SwingWrapper<XYChart>(grafica);
        datos.displayChart();

        graficaAvea1 = new GraficaDeDatosAvea();
        graficaAvea1.execute();
    }

    private class GraficaDeDatosAvea extends SwingWorker<Boolean, double[]>
    {
        LinkedList<Double> manejoGrafica = new LinkedList<Double>();
        public GraficaDeDatosAvea()
        {
            manejoGrafica.add(0.0);
        }

        @Override
        protected Boolean doInBackground() throws Exception
        {
            String valorEntrante;
            double valorEntranteDouble;

            while(!isCancelled())
            {
                try
                {
                    while (true)
                    {
                        if(System.in.available() > 0)
                        {
                            String s = entradaPuertos.nextLine() + "\n";
                            byte[] buffer = s.getBytes();
                            comPorts[port].writeBytes(buffer,buffer.length);
                        }
                        if(comPort.bytesAvailable() > 0)
                        {
                            byte[] data = new byte[10];
                            comPort.readBytes(data,1);
                            System.out.println((char)data[0]);
                            if((char)data[0] >= ' ')
                            {
                                text.append((char)data[0]);
                            }
                            else
                            {
                                if((char)data[0] == '\n')
                                {
                                    valorEntrante=text.toString();
                                    valorEntranteDouble=Integer.parseInt(valorEntrante);
                                    manejoGrafica.add(valorEntranteDouble);
                                    if(manejoGrafica.size() > 250)
                                    {
                                        manejoGrafica.removeFirst();
                                    }
                                    double[] arregloDatos = new double[manejoGrafica.size()];
                                    for (int j = 0; j < manejoGrafica.size(); j++)
                                    {
                                        arregloDatos[j] = manejoGrafica.get(j);
                                    }
                                    publish(arregloDatos);
                                    try
                                    {
                                        Thread.sleep(8);
                                    }
                                    catch (InterruptedException ae)
                                    {
                                        System.out.println("Ha ocurrido un error en la comunicación con el controlador\ndel ventilador, llame a Leonette y ruegue que esto funcione");
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                    comPorts[port].closePort();
                }
            }
            return true; //TERMINAR
        }

        @Override
        protected void process(List<double[]> chunks)
        {
            double[] datosActualesSPI = chunks.get(chunks.size()-1);
            grafica.updateXYSeries("Arduino Coms", null, datosActualesSPI, null);
            datos.repaintChart();
            long inicio = System.currentTimeMillis();
            long duracion = System.currentTimeMillis() - inicio;

            try
            {
                Thread.sleep(7 - duracion);
            }
            catch (InterruptedException aei)
            {
                System.out.println("Algo falló y ahora no sabemos qué \nDe nuevo llame a Leonette y reze a su santo favorito");
            }
        }
    }

    static void openCOMport() {
        comPort = SerialPort.getCommPorts()[port];
        System.out.println("Estableciendo conexión con el puerto: " +  comPorts[port].getDescriptivePortName() + "\n");
        if(!comPort.openPort())
        {
            System.out.println("Comunicación fallida" + comPorts[port].getDescriptivePortName() + "\n"); port=-1; return;
        }
        else
        {
            System.out.println("Puerto abierto exitosamente: " + comPorts[port].getDescriptivePortName() + "\n\t\tOK\n");
            comPort.setBaudRate(115200);
        }
    }
}

Idk if you know something I'm doing wrong. Thank you in advance and for the past help :1st_place_medal:

what is the error message? compile or run time?
are using an IDE such as NetBeans or just compiling in the Command Prompt using javac

I copied the jar files from xchart-change-log

xchart-3.8.2.jar
xchart-demo-3.8.2.jar

then ran demo in the Windows command prompy

F:\temp>java -cp xchart-demo-3.8.2.jar;xchart-3.8.2.jar org.knowm.xchart.demo.XChartDemo

displays
image

your need to add to your java code

import java.util.LinkedList;

it will then compile and run

> run ConsoleAndGraphGen
Lista de puertos COM
No se encontraron puertos disponibles
Puerto COM[0] = Communications Port (COM1)
Puerto COM[1] = CP2102 USB to UART Bridge Controller


Ingrese el puerto a enlazar previo a graficar los datos de presión:

I assume it is then waiting for data?

1 Like

I'm using IntelliJ IDEA and the problem is on the runtime

java.lang.NumberFormatException: For input string: "-165.71"
	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
	at java.base/java.lang.Integer.parseInt(Integer.java:665)
	at java.base/java.lang.Integer.parseInt(Integer.java:781)
	at ConsoleAndGraphGen$GraficaDeDatosAvea.doInBackground(ConsoleAndGraphGen.java:124)
	at ConsoleAndGraphGen$GraficaDeDatosAvea.doInBackground(ConsoleAndGraphGen.java:84)
	at java.desktop/javax.swing.SwingWorker$1.call(SwingWorker.java:304)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at java.desktop/javax.swing.SwingWorker.run(SwingWorker.java:343)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.Thread.run(Thread.java:1589)

The string is getting bigger

java.lang.NumberFormatException: For input string: "-165.7171-165.71-165.71-165.71-165.71-165.71-165.71-165.71-165.71-165.71-165.71-165.71"

The other lines are the same

The code is the one above, it opens the chart window but doesn't run as intended

The -165.71 number is the expected data

Again, really really thannk you

you are calling Integer.parseInt() but you input line

-165.71

looks like a float, i.e. it has a . indicating a fractional component

I use Dr Java for simple programs or NetBeans for large projects

1 Like

Well, now it has a diferent error

java.lang.NumberFormatException: multiple points
	at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1914)
	at java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)

This substitutes the first line error. Thanks for noticing my mistake

I assume it is because you are attempting to parse a string such as "-165.7171-165.71-165.71"
are you failing to clear the string after parseing it

1 Like

I found the method to clean it, was:

text.delete(int_firstBit, int_lastBit);

Thanks for all your help :1st_place_medal: :heart:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.