Sap, Habr. Perhaps people starting arduino will be interested in how to quickly and easily organize the transfer of information between a microcontroller and a Java application. This bundle opens up a bunch of interesting possibilities for collecting and processing data from sensors, managing various whistles, and creating their first IoT projects.
Recently, on the Internet, I stumbled upon a very simple
Java-Arduino Communication Library. Not finding publications on this topic here, I decided to share with you the experience of using. To work, we will need the
Arduino IDE ,
IntelliJ IDEA ,
Java SE Development Kit and, in fact, the microcontroller itself (I tested it on the Chinese Arduino Nano and
Strela based on Leonardo Leonardo, everything worked perfectly for both).
The task is simple - we will create a console application that, when launched, establishes a Serial connection with a microcontroller and waits for the user to enter a string in an infinite loop. Depending on the entered string, the following options are possible:
- "On" - the microcontroller includes an integrated LED;
- "Off" - the microcontroller turns off the built-in LED;
- "Exit" - the microcontroller turns off the built-in LED, and the application exits.
Sketch for the microcontroller
Building a system, let's start by writing and uploading a sketch to Arduino Nano. Nothing too complicated. In the “setup” block, we configure the pin with the LED and the Serial-port, and in the “loop” block we listen to the Serial-port for incoming bytes. Depending on the received value, we perform this or that operation.
')
Sketch source code #define LED_PIN = 13 void setup() { // Serial- 9600 /c Serial.begin(9600); // pinMode(LED_PIN, OUTPUT); } void loop() { // Serial- () if (Serial.available() != 0) { // () byte b = Serial.read(); // '1', if (b == 49) digitalWrite(LED_PIN, HIGH); // '0', if (b == 48) digitalWrite(LED_PIN, LOW); }
A little explanation and attention is required only to check the conditions (b == 49) and (b == 48). If you do not understand why, then welcome under the spoiler:
The answer to the main question of life, the universe and all thatThe thing is that when sending a symbol (Chr) '1' to the microcontroller via a Serial-connection,
ASCII is used , in which the character '1' is encoded with an integer decimal value (Dec) 49. When reading a character with a microcontroller, the value of the character is '1' assigned to the integer variable byte b. That is, in fact, the value of b is 49.
To check at this stage, you can send 1 and 0 from the monitor built into the Arduino IDE. If the LED on the board does not turn on / off, then look for the error in your sketch.
Java application
Now run IntelliJ IDEA and create a new Java project. To work, you need to connect two additional libraries:
jSerialComm-1.3.11.jar and arduino.jar . How to add downloaded jar-archives can be read
here .
The entire application will consist of a single class:
Java source code import arduino.Arduino; import java.util.Scanner; public class AppMain { public static void main(String[] args) throws InterruptedException { Scanner scanner = new Scanner(System.in); Arduino arduino = new Arduino("COM52", 9600); boolean connected = arduino.openConnection(); System.out.println(" : " + connected); Thread.sleep(2000); label_1: while (scanner.hasNext()) { String s = scanner.nextLine(); switch (s) { case "on": arduino.serialWrite('1'); break; case "off": arduino.serialWrite('0'); break; case "exit": arduino.serialWrite('0'); arduino.closeConnection(); break label_1; default: System.out.println(s + " - "); break; } } } }
To work with the COM port, an Arduino class object is created. The constructor takes two parameters:
- String portDescrition - COM port name
- int baud_rate - transfer rate
It is better to specify these parameters immediately in the constructor, but you can set them separately using setters. The name of the COM port can be viewed in the Arduino IDE, or in the device manager. The transfer speed must match the one specified in the “setup” block of the sketch for the microcontroller, in this case 9600 baud / c:
void setup() { // Serial- 9600 /c Serial.begin(9600); // pinMode(LED_PIN, OUTPUT); } }
Next, you need to establish a connection using the openConnection () method. The method returns true if the connection is successful. We will output this value to the console to make sure that the actions performed are correct.
Important: after opening the connection, you must pause using the Thread.sleep () method, in this case 2000 milliseconds. Arduino Nano turned out to be a real brawl compared to Strela, which could be sent immediately after the connection was established. It is possible that your controller will need even more time. Therefore, if the connection is established, the data is sent, but does not come, then first of all increase the amount of pause.
Now we enter an infinite loop and start waiting for input from the user:
label_1: while (scanner.hasNext()) { String s = scanner.nextLine(); switch (s) { case "on": arduino.serialWrite('1'); break; case "off": arduino.serialWrite('0'); break; case "exit": arduino.serialWrite('0'); arduino.closeConnection(); break label_1; default: System.out.println(s + " - "); break; } }
When you enter the next string and press "enter", it is read and saved in the variable String s. Depending on the value of this string, the switch statement sends the character '1' or '0' to the microcontroller using the serialWrite (char c) method. Do not forget that when the microcontroller receives these symbols and stores them in an integer variable, you will get 49, or 48).
In general, you can use the following overloaded methods of the Arduino class to send data:
- public void serialWrite (String s);
- public void serialWrite (char c);
- public void serialWrite (String s, int noOfChars, int delay);
- public void serialWrite (char c, int delay);
As you can see, you can send the entire string, the character and part of the characters of the string (noOfChars). In the latter two methods, you can specify a pause after sending the next character. However, the string will still be sent character by character (or, to be more precise, bit by bit). Therefore, if you do not transmit any particular value (for example, the angle to which the connected servo drive is to be installed), then it is easier to send just one character.
At the end of the program, it is desirable to close the COM-port using the close.connection () method so that when you restart the program you do not get an error related to the fact that the COM port is still busy, and to exit from an infinite loop waiting for a string, use the operator break with the
label_1 label, which allows you to exit the loop, preceded by the corresponding label:
case "exit": arduino.serialWrite('0'); arduino.closeConnection(); break label_1;
That's all for today. I hope the article will be something useful for you. Soon I will try to write the following one, which will consider the possibility of not only sending, but also receiving data from the microcontroller using the example of a more applied and functional application.