Monthly Archives: December 2017

Tutorial: Serial Connection between Java Application and Arduino Uno

In this tutorial, I demonstrate how to build up a serial connection between a Java Application and an Arduino Uno. The tutorial is divided into two parts: In the first part, it is explained how to send text (digits) from a Java Application to an Arduino. Moreover, the Arduino will print out the digits to an LCD module (LCM1602 IIC V1). In the second part, basically the same Java application is used to send digits to the Arduino – but this time with the help of a USB-to-TTL module. As a result, the Arduino’s standard serial port can be used by the Arduino IDE to print the received digits to the serial monitor.

Notes:
– I added all source codes files to a github repository: https://github.com/mschoeffler/arduino-java-serial-communication
I made also a video tutorial

List of materials:
– Arduino Uno (for Example Part 1&2) [Search on Aliexpress | Amazon]
– LCM1602 IIC V1 / LCD module (for Example Part 1) [Search on Aliexpress | Amazon]
– USB-to-TTL Serial Adapter (for Example Part 2) [Search on Aliexpress | Amazon]

Example Part 1

Setup
In this part, we have to wire an LCM1602 IIC V1 to the Arduino. The LCM1602 has four pins: VCC, GND, SDA, and SCL. The wiring is straightforward: VCC goes to the Arduino’s 5V. The other three pins have the exact same names on the Arduino: GND goes to GND, SDA to SDA, and SCL to SCL. Have a look at the fritzing file for more details:

Fritzing files that shows how to wire an LCM1602 IIC V1 module to an Arduino Uno.

Fritzing files that shows how to wire an LCM1602 IIC V1 module to an Arduino Uno.

Arduino Source Code
Next, we have to write some code for the Arduino Uno. Basically, the code just waits for bytes ready to be read by the serial port. If a byte was read, it is printed out to the LCM1602 IIC V1 module.

// (c) Michael Schoeffler 2017, http://www.mschoeffler.de
#include <Wire.h>
#include <LiquidCrystal_I2C.h> // LiquidCrystal_I2C library
 
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // 0x27 is the i2c address of the LCM1602 IIC v1 module (might differ)

void setup() {
  lcd.begin(16, 2); // begins connection to the LCD module
  lcd.backlight(); // turns on the backlight
  lcd.clear(); 

  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect.
  }

  lcd.setCursor(0, 0); // set cursor to first row
  lcd.print("Init done"); // print to lcd
 
}

void loop() {
  if (Serial.available() > 0) {    
    byte incomingByte = 0;
    incomingByte = Serial.read(); // read the incoming byte:
    if (incomingByte != -1) { // -1 means no data is available
      lcd.setCursor(0, 0); // set cursor to first row
      lcd.print("I received: "); // print out to LCD
      lcd.setCursor(0, 1); // set cursor to secon row
      lcd.print(incomingByte); // print out the retrieved value to the second row
    }
  }
}

Java Source Code
The Java application uses the jSerialComm library to send text to an Arduino Uno via a standard USB connection. I made use of Maven to set up the dependency between my Java project and the jSerialComm library. If you also use Maven for your project, then my POM file might be of use to you:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>de.mschoeffler.arduino.serialcomm</groupId>
  <artifactId>de.mschoeffler.arduino.serialcomm.example01</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>ArduinoBasicExample</name>
  <build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.5.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <dependencies>
    <dependency>
     <groupId>com.fazecast</groupId>
     <artifactId>jSerialComm</artifactId>
     <version>1.3.11</version>
  </dependency>
  </dependencies>
</project>

The actual Java source code is only a single class with a main method. A serial connection is established. Then, five digits (0-4) are written to the serial port. Finally, the serial connection is closed:

package de.mschoeffler.arduino.serialcomm.example01;

import java.io.IOException;
import com.fazecast.jSerialComm.SerialPort;

/**
 * Simple application that is part of an tutorial. 
 * The tutorial shows how to establish a serial connection between a Java and Arduino program.
 * @author Michael Schoeffler (www.mschoeffler.de)
 *
 */
public class Startup {

  public static void main(String[] args) throws IOException, InterruptedException {
    SerialPort sp = SerialPort.getCommPort("/dev/ttyACM1"); // device name TODO: must be changed
    sp.setComPortParameters(9600, 8, 1, 0); // default connection settings for Arduino
    sp.setComPortTimeouts(SerialPort.TIMEOUT_WRITE_BLOCKING, 0, 0); // block until bytes can be written
    
    if (sp.openPort()) {
      System.out.println("Port is open :)");
    } else {
      System.out.println("Failed to open port :(");
      return;
    }		
    
    for (Integer i = 0; i < 5; ++i) {			
      sp.getOutputStream().write(i.byteValue());
      sp.getOutputStream().flush();
      System.out.println("Sent number: " + i);
      Thread.sleep(1000);
    }		
    
    if (sp.closePort()) {
      System.out.println("Port is closed :)");
    } else {
      System.out.println("Failed to close port :(");
      return;
    }
    

  }

}

The main important method call is SerialPort.getCommPort(...).  The method has only one argument which has to be the device name of your Arduino Uno. Therefore, it is very likely that you need to change this argument value. You can find out the device name of your Arduino Uno by having a look to the Arduino IDE. In Tools->Port you find all connected devices. In order to upload code to an Arduino, you have to select the correct device name of the corresponding Arduino. Luckily, the same device name is needed by the jSerialComm library. So simply copy the device name from your Arduino IDE to the Java source code.

Execution
When you have uploaded the source code to the Arduino and started the java application, you should see that the digits 0-4 appear on the LCM1602 IIC V1 module. Sometimes, I have problems executing this code, if I use cheap Arduino clones. Luckily, it always executes perfectly on my original Arduino Uno from Italy ;)

Example 2

In the second part of this tutorial, the digits (coming from the Java application) are printed to the default serial connection of the Arduino. As a result, the received digits can be viewed from the Arduino IDE’s serial monitor (Tools -> Serial Monitor). Unfortunately, as a consequence, the standard USB connection cannot be used by the Java application since the serial monitor will already catch the serial port as soon as we open it. Therefore, we make use of a USB-to-TTL serial adapter.

Setup
Typically, a USB-to-TTL adapter has at least four pins: VCC, GND, RX (receive data), and TX (transmit data). As we will use this adapter only to send data from the Java application, we can ignore the RX pin. VCC must be connected to the Arduino’s 5V pin, GND must be connected to the Arduino’s GND pin, and TX must be connected to the Arduino digital pin #5 (also other digital pins can be used).

Fritzing file that shows how to connect a USB-to-TTL serial adapter to an Arduino Uno.

Fritzing file that shows how to connect a USB-to-TTL serial adapter to an Arduino Uno.

Here you see how my setup looks like (including the serial adapter):

USB-to-TTL serial adapter connected to an Arduino Uno.

USB-to-TTL serial adapter connected to an Arduino Uno.

Arduino Source Code:
The Arduino program makes use of a so-called software serial. When a software serial object is initialized, it requires the pin numbers of the receive and transmit pin. As we do not plan to transmit text from the Arduino Uno, we can set the transmit pin to any number. Here, I simply set it to 6.

// (c) Michael Schoeffler 2017, http://www.mschoeffler.de
#include <SoftwareSerial.h>
 
SoftwareSerial sserial(5,6); // receive pin (used), transmit pin (unused)

void setup() {
  Serial.begin(9600); // used for printing to serial monitor of the Arduino IDE
  sserial.begin(9600); // used to receive digits from the Java application
  while (!Serial) {
    ; // wait for serial port to connect. 
  }
}

void loop() {
  if (sserial.available() > 0) {
    byte incomingByte = 0;
    incomingByte = sserial.read();
    if (incomingByte != -1) {
      Serial.print("I received: "); // print out to serial monitor
      Serial.println(incomingByte); // print out to serial monitor
    }
  }
}

Java source code:
The Java application is basically the same than the one used in part one of this tutorial. The only exception is the device name of the USB-to-TTL device. Conveniently, you can again make use of the Arduino IDE as it will show you the name of the serial adapter, too.

Execution:
If everything was successfully executed, the serial monitor of the Arduino IDE should show five received digits.

Shows the result of a serial connection between a Java application (Eclipse IDE) and an Arduino Uno (Arduino IDE / serial monitor).

Shows the result of a serial connection between a Java application (Eclipse IDE) and an Arduino Uno (Arduino IDE / serial monitor).

Video Tutorial:

 

DIY: Y-Adapter Jumper Wire

In a lot of situations, it would be useful to have a Y-shaped jumper wire to split signals. For example, many variants of the Arduino Uno have only a single 5V pin. Unfortunately, most breakout boards require to connect their GND and 5V pins to the Arduino. If you do not use a breadboard, this can become very annoying due to the very limited amount of only a single 5V pin. Moreover, if you want to share a signal with an Arduino Uno and an oscilloscope, a Y-adapter for your pin could come in handy, too.

When I was looking for such Y-shaped jumper wires on shopping portals, I was a bit surprised that I could barely find any offer. Therefore, I decided to make my own Y-shaped jumper wire. If you are new with crimping connectors, it makes sense to have a look at my previous crimping tutorial.

List of Materials and Tools:
– Wire (e.g., 28AWG/0.5mm²) [Search on Aliexpress | Amazon]
– DuPont connector [Search on Aliexpress | Amazon]
– DuPont connector shell [Search on Aliexpress | Amazon]
– Engineer NS-04 Micro nippers [Search on Aliexpress | Amazon]
– Engineer PA-14 Wire Stripper [Search on Aliexpress | Amazon]
– Engineer PA-09 connector pliers [Search on Aliexpress | Amazon]

Instructions:

First, I took two wires and cut them to the same length:

Next, for each wire, I stripped off the insulation of both ends:

Then, I did the actual crimping. The main difference between crimping conventional jumper wires and my Y-adapter is that two wires are crimped to a single connector on one end:

The remaining other two ends are crimped as usual:

Then, the housings must be put on each connector. The connector with two wires just fits to the housing. In case the housing does not slide in easily, I recommend to use the help of a pair of pliers.

And here is the result:

I made four times the same Y-adapter type (1x male to 2x female). Basically, you can make any type of Y-adapter that you want. The only thing you need is a sufficient amount of female- and male connectors, connector housings, and wire. Now, I’m able to easily split the signal coming from a breakout board without the need of a breadboard. Here is an example where I split the signal of a joystick breakout between an Arduino and an oscilloscope:

 

By the way, another possibility of splitting a signal without a breadboard is to use PCB terminals. A PCB’s pin fits perfectly to the female pin of an Arduino Uno:

Video Tutorial:

 

 

Example Application: GY-521 module (MPU-6050 breakout board) and Arduino Uno

Example application that shows how to use the raw values of the GY-521 to blink LEDs based on the position of a breadboard.

Example application that shows how to use the raw values of the GY-521 to blink LEDs based on the position of a breadboard.

In a previous blog post, I wrote a short tutorial about the GY-521 module (MPU-6050 breakout board). In addition to the blog post, I made a video tutorial that had basically the same content. At the end of the video tutorial, I presented a small example application that was not described in the blog post. Due to a request, I decided to share the setup and code of the small example which is presented in the following:

The example is very simple. Four LEDs are put in holes at the four corners of a breadboard. In the center of the breadboard is a small breadboard. The GY-521 is used to detect which side of the small breadboard is moved to the top. In order to indicate the “highest side”, two corresponding LEDs are switched on. This example is shown at around 7:15 in the video tutorial.

Wiring:

Fritzing file of the GY-521 example application.

Fritzing file of the GY-521 example application.

Source code:

// (c) Michael Schoeffler 2017, http://www.mschoeffler.de

#include "Wire.h" // This library allows you to communicate with I2C devices.

const int MPU_ADDR=0x68; // I2C address of the MPU-6050. If AD0 pin is set to HIGH, the I2C address will be 0x69.

int16_t accelerometer_x, accelerometer_y, accelerometer_z; // variables for accelerometer raw data
int16_t gyro_x, gyro_y, gyro_z; // variables for gyro raw data
int16_t temperature; // variables for temperature data

#define LED_LB 2 // LED left bottom
#define LED_RB 3 // LED right bottom
#define LED_RT 4 // LED right top
#define LED_LT 5 // LED left top

char tmp_str[7]; // temporary variable used in convert function

char* convert_int16_to_str(int16_t i) { // converts int16 to string. Moreover, resulting strings will have the same length in the debug monitor.
  sprintf(tmp_str, "%6d", i);
  return tmp_str;
}

void setup() {
  Serial.begin(9600);
  pinMode(LED_LB, OUTPUT);
  pinMode(LED_RB, OUTPUT);
  pinMode(LED_RT, OUTPUT);
  pinMode(LED_LT, OUTPUT);
  digitalWrite(LED_LB, LOW);
  digitalWrite(LED_RB, LOW);
  digitalWrite(LED_RT, LOW);
  digitalWrite(LED_LT, LOW);
  Wire.begin();
  Wire.beginTransmission(MPU_ADDR); // Begins a transmission to the I2C slave (GY-521 board)
  Wire.write(0x6B); // PWR_MGMT_1 register
  Wire.write(0); // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
}
void loop() {
  Wire.beginTransmission(MPU_ADDR);
  Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) [MPU-6000 and MPU-6050 Register Map and Descriptions Revision 4.2, p.40]
  Wire.endTransmission(false); // the parameter indicates that the Arduino will send a restart. As a result, the connection is kept active.
  Wire.requestFrom(MPU_ADDR, 7*2, true); // request a total of 7*2=14 registers
  
  // "Wire.read()<<8 | Wire.read();" means two registers are read and stored in the same variable
  accelerometer_x = Wire.read()<<8 | Wire.read(); // reading registers: 0x3B (ACCEL_XOUT_H) and 0x3C (ACCEL_XOUT_L)
  accelerometer_y = Wire.read()<<8 | Wire.read(); // reading registers: 0x3D (ACCEL_YOUT_H) and 0x3E (ACCEL_YOUT_L)
  accelerometer_z = Wire.read()<<8 | Wire.read(); // reading registers: 0x3F (ACCEL_ZOUT_H) and 0x40 (ACCEL_ZOUT_L)
  temperature = Wire.read()<<8 | Wire.read(); // reading registers: 0x41 (TEMP_OUT_H) and 0x42 (TEMP_OUT_L)
  gyro_x = Wire.read()<<8 | Wire.read(); // reading registers: 0x43 (GYRO_XOUT_H) and 0x44 (GYRO_XOUT_L)
  gyro_y = Wire.read()<<8 | Wire.read(); // reading registers: 0x45 (GYRO_YOUT_H) and 0x46 (GYRO_YOUT_L)
  gyro_z = Wire.read()<<8 | Wire.read(); // reading registers: 0x47 (GYRO_ZOUT_H) and 0x48 (GYRO_ZOUT_L)
  
  // print out data
  Serial.print("aX = "); Serial.print(convert_int16_to_str(accelerometer_x));
  Serial.print(" | aY = "); Serial.print(convert_int16_to_str(accelerometer_y));
  Serial.print(" | aZ = "); Serial.print(convert_int16_to_str(accelerometer_z));
  // the following equation was taken from the documentation [MPU-6000/MPU-6050 Register Map and Description, p.30]
  Serial.print(" | tmp = "); Serial.print(temperature/340.00+36.53);
  Serial.print(" | gX = "); Serial.print(convert_int16_to_str(gyro_x));
  Serial.print(" | gY = "); Serial.print(convert_int16_to_str(gyro_y));
  Serial.print(" | gZ = "); Serial.print(convert_int16_to_str(gyro_z));
  Serial.println();
  
  if (accelerometer_x < 1000 && accelerometer_y < -8000) {
    digitalWrite(LED_LB, HIGH);
    digitalWrite(LED_RB, HIGH);
    digitalWrite(LED_RT, LOW);
    digitalWrite(LED_LT, LOW);
  } else if (accelerometer_x < 1000 && accelerometer_y > 8000) {
    digitalWrite(LED_LB, LOW);
    digitalWrite(LED_RB, LOW);
    digitalWrite(LED_RT, HIGH);
    digitalWrite(LED_LT, HIGH);
  } else if (accelerometer_x > 8000 && accelerometer_y < 1000) {
    digitalWrite(LED_LB, LOW);
    digitalWrite(LED_RB, HIGH);
    digitalWrite(LED_RT, HIGH);
    digitalWrite(LED_LT, LOW);
  } else if (accelerometer_x < -8000 && accelerometer_y < 1000) {
    digitalWrite(LED_LB, HIGH);
    digitalWrite(LED_RB, LOW);
    digitalWrite(LED_RT, LOW);
    digitalWrite(LED_LT, HIGH);
  } else {
    digitalWrite(LED_LB, LOW);
    digitalWrite(LED_RB, LOW);
    digitalWrite(LED_RT, LOW);
    digitalWrite(LED_LT, LOW);
  }
  
  // delay
  delay(10);
}

 

 

Arduino Tutorial: HX711 Load Cell Amplifier (Weight Sensor Module) + LCM1602 IIC V1 LCD

In this tutorial, it is shown how to utilize an Arduino Uno, a HX711 breakout board, and a load cell in order to measure weight. Moreover, an LCD module of type LCM1602 IIC V1 is used to display the measured weight.

List of materials:
– Arduino Uno [Search on Aliexpress | Amazon]
– Jumper wires [Search on Aliexpress | Amazon]
– HX711 Load Cell Amplifier [Search on Aliexpress | Amazon]
– Load Cell [Search on Aliexpress | Amazon]
– LCM1602 IIC V1 (LCD) [Search on Aliexpress | Amazon]
– Small squared timber and screws

A load cell (left hand side) and an HX711 breakout board (right hand side).

A load cell (left hand side) and an HX711 breakout board (right hand side).

The HX711 is a 24-bit analog-to-digital converter which fits perfectly to weight scale applications. Fortunately, there exist many breakout boards for the HX711. Therefore, it is very easy to use it in combination with a so-called load cell. Load cells are transducers that convert pressure/force into an electrical signal. As the electrical signal has typically only a few millivolts, it has to be amplified. And that’s where the HX711 breakout board comes in:  as it amplifies the weak signal to a few volts so that we can read the signal with the help of an Arduino Uno.

Preparations for Wiring:
In order to easily connect the load cell to the pins of the HX711 module, you can add DuPont connectors to the wires. This step is totally optional. You can use whatever you want to connect the wires to module’s pins. If you use DuPont connectors, keep in mind that such load cells often have thin single-strand wires. I used the help of some solder to attach the thin wires more tightly to their connectors.

Preparation of crimping tools, raw connectors, and shells in order to add DuPont connectors to the wires of the load cell. As a result, the load cell can be easily connected to the HX711 breakout board.

Preparation of crimping tools, raw connectors, and shells in order to add DuPont connectors to the wires of the load cell. As a result, the load cell can be easily connected to the HX711 breakout board.

Preparation of crimping tools, raw connectors, and shells in order to add DuPont connectors to the wires of the load cell. As a result, the load cell can be easily connected to the HX711 breakout board.

Load cell with DuPont connectors.

You will retrieve consistent pressure values from the load cell, if you mount the load cell on something that is solid and heavy. I used a part of an old squared timber for this task:

Load cell mounted on squared timber.

Load cell mounted on squared timber.

Wiring:

Fritzing file that shows how to connect the load cell to the HX711 module. Moreover, it is shown how to connect the HX711 module and the LCM1602 IIC v1 (LCD) module to the Arduino.

Fritzing file that shows how to connect the load cell to the HX711 module. Moreover, it is shown how to connect the HX711 module and the LCM1602 IIC v1 (LCD) module to the Arduino.

First, the load cell is connected to the HX711 module. The load cell has four wires, which must be connected to the first four pins of the HX711 module: Red wire to E+, black wire to E-, white wire to A-, and green wire to A+. The remaining pins, B- and B+, can be used if a second load cell has to be connected to the HX711 module.
Next, the HX711 module is connected to the Arduino Uno. The module’s GND pin must be connected to the Arduino’s GND pin. DT and SCK must be connected to digital pins of the Arduino. In this tuorial, DT is connected to digital pin #4 and SCK is connected to digital pin #5. The remaining pin VCC must be connected to the 5V pin of the Arduino. As the LCM1602 module requires also a connection to the 5V pin, a breadboard is used in-between to split the Arduino’s 5V signal.
As a last step, the LCM1602 module’s SDA and SCL pins must be connected to the corresponding SDA and SCL pins of the Arduino Uno. Moreover, the GND pin must be connected to one of the Arduino’s GND pins and the VCC pin has to be connected to the 5V signal of the breadboard.

Example source code:

// (c) Michael Schoeffler 2017, http://www.mschoeffler.de
#include <HX711_ADC.h> // https://github.com/olkal/HX711_ADC
#include <Wire.h>
#include <LiquidCrystal_I2C.h> // LiquidCrystal_I2C library

HX711_ADC LoadCell(4, 5); // parameters: dt pin, sck pin<span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // 0x27 is the i2c address of the LCM1602 IIC v1 module (might differ)

void setup() {
  LoadCell.begin(); // start connection to HX711
  LoadCell.start(2000); // load cells gets 2000ms of time to stabilize
  LoadCell.setCalFactor(999.0); // calibration factor for load cell => strongly dependent on your individual setup
  lcd.begin(16, 2); // begins connection to the LCD module
  lcd.backlight(); // turns on the backlight
}

void loop() {
  LoadCell.update(); // retrieves data from the load cell
  float i = LoadCell.getData(); // get output value
  lcd.setCursor(0, 0); // set cursor to first row
  lcd.print("Weight[g]:"); // print out to LCD
  lcd.setCursor(0, 1); // set cursor to secon row
  lcd.print(i); // print out the retrieved value to the second row
}

 

Calibration

The last step is to calibrate the weighing scale. This steps becomes very easy if you have some calibration weights. Unfortunately, I do not have such weights. Therefore, I used an alternative approach to calibrate my weighing scale. First, I grabbed another weighing scale and put something on it (dc motor):

Then I put the dc motor on my weighing scale. Next, I adapted the parameter of the setCalFactor method (see setup function) until the correct weight was shown on my weighing scale. Keep in mind, each load cell and setup needs a different calibration factor. Therefore, it makes no sense to tell you mine.

In order to check whether my calibration factor is working, I did the same thing again with something else (screwdriver):

Overall, I’m satisfied with the accuracy:

Video Tutorial: