J’aime bien Arduino, et j’aime bien Java… Donc l’idée de faire communiquer un microcontrôleur Arduino avec Java m’est venue tout naturellement.
J’ai donc commencé par suivre quelques tutoriels, puis encore d’autres car finalement, ce n’est pas si simple que cela… en tous cas la première fois.
Ce tutoriel est fortement inspiré / traduit du super site http://dummyscodes.blogspot.fr/
Merci à lui.
Pour cette fois, je me base sur un ordinateur sous Windows 10 et une carte Arduino Explora.
Donc, pour pouvoir faire communiquer un Arduino avec Java, le plus simple est d’utiliser les librairies RxTx téléchargeables ici ou ici.
Décompressez les fichiers dans un dossier.
Créons maintenant un nouveau projet sous Eclipse nommé RxTxTest :
Créons ensuite une nouvelle classe « CommPortTest.java » :
Maintenant, il faut ajouter la librairie RxTx au projet. Pour cela, faites un clic droit sur le projet, puis cliquez sur « Build Path » -> « Configure Build Path » -> onglet « Libraries » -> « Add External JARs », sélectionner le fichier « RXTXComm.jar » situé dans le dossier précédemment décompressé, et enfin cliquez sur « OK » :
Enfin, copiez dans le projet les 2 fichiers *.dll situés dans le même dossier décompressé précédemment.
Pour pouvoir communiquer, il faut demander à l’Arduino d’envoyer des données. Voici le prog utilisé (ici sur une carte Explora) :
Et le code de la classe RxTxTest :
————————————– code ———————————–
import gnu.io.*;
import java.util.Enumeration;
public class CommPortTest {
public static void main(String[] args) {
System.out.println(« Program Started!!! »);
CommPortIdentifier serialPortId;
Enumeration enumComm;
enumComm = CommPortIdentifier.getPortIdentifiers();
while(enumComm.hasMoreElements())
{
serialPortId = (CommPortIdentifier)enumComm.nextElement();
if(serialPortId.getPortType() == CommPortIdentifier.PORT_SERIAL)
{
System.out.println(serialPortId.getName());
}
}
System.out.println(« Program Finished Sucessfully »);
}
}
————————————– /code ———————————–
Ce programme trouve et affiche le numéro du port sur lequel est connecté la carte Arduino. Ici, il s’agit du port Com12 :
Enfin, nous pouvons créer et coder une nouvelle classe nommée SerialTest, inspirée de la doc officielle d’Arduino (attention, ne pas oublier de modifier le port !) :
————————————– code ———————————–
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.util.Enumeration;
public class SerialTest implements SerialPortEventListener {
SerialPort serialPort;
/** The port we’re normally going to use. */
private static final String PORT_NAMES[] = {« /dev/tty.usbserial-A9007UX1 », // Mac OS X
« /dev/ttyUSB0 », // Linux
« COM12 », // Windows
};
private BufferedReader input;
private OutputStream output;
private static final int TIME_OUT = 2000;
private static final int DATA_RATE = 9600;
public void initialize() {
CommPortIdentifier portId = null;
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
//First, Find an instance of serial port as set in PORT_NAMES.
while (portEnum.hasMoreElements()) {
CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
for (String portName : PORT_NAMES) {
if (currPortId.getName().equals(portName)) {
portId = currPortId;
break;
}
}
}
if (portId == null) {
System.out.println(« Could not find COM port. »);
return;
}
try {
serialPort = (SerialPort) portId.open(this.getClass().getName(),
TIME_OUT);
serialPort.setSerialPortParams(DATA_RATE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
// open the streams
input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
output = serialPort.getOutputStream();
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
} catch (Exception e) {
System.err.println(e.toString());
}
}
public synchronized void close() {
if (serialPort != null) {
serialPort.removeEventListener();
serialPort.close();
}
}
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
String inputLine=null;
if (input.ready()) {
inputLine = input.readLine();
String [] chunks = inputLine.split(« , »);
System.out.println(inputLine);
System.out.println(chunks[0] + « \t » + chunks[1] + « \t » + chunks[2] + « \t »);
}
} catch (Exception e) {
System.err.println(e.toString());
}
}
// Ignore all the other eventTypes, but you should consider the other ones.
}
public static void main(String[] args) throws Exception {
SerialTest main = new SerialTest();
main.initialize();
Thread t=new Thread() {
public void run() {
//the following line will keep this app alive for 1000 seconds,
//waiting for events to occur and responding to them (printing incoming messages to console).
try {Thread.sleep(1000000);} catch (InterruptedException ie) {}
}
};
t.start();
System.out.println(« Started »);
}
}
————————————– /code ———————————–
Cela donne chez moi :
Cool ! La carte Arduino et Eclipse communiquent !
Maintenant, on peut tout envisager, que cela soit en matière d’interfaces graphiques ou de fonctionnalités.
Bon, il y a quand même une « java.lang.ArrayIndexOutOfBoundsException » qui m’échappe pour le moment, mais je m’en occuperai avant de me lancer dans des projets plus ambitieux !
MAJ du 01/01/19 : n’ayant pas le temps de tester, je vous mets la solution trouvée par Johann pour éviter l’exception :
»
Merci beaucoup pour ce petit tuto Arduino/Java.
Une petite chose à te suggérer pour éviter « java.lang.ArrayIndexOutOfBoundsException » voici ce que j’ai fait (un petit ajout de Try catch et ça marche :
try {
System.out.println(chunks[0] + » \t » + chunks[1] + » \t » + chunks[2] + » \t « );
} catch (Exception e) {}
En te remerciant encore pour ce très bon tuto
Bien Cordialement
Johann
»
Comme d’habitude, si vous avez des questions / idées, n’hésitez pas, c’est par ici :