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.
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
your program writes the sensor data to Serial where it would appear on the Arduino IDE Serial Monitor
close the Serial Monitor
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
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
That was so useful, I'm so close to get it right thanks to you
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
> 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'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
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