Moving a Servo With Arduino and a Java App

by jjosemayorga in Circuits > Arduino

296 Views, 1 Favorites, 0 Comments

Moving a Servo With Arduino and a Java App

Miniatura.png

In this Instructable I'll show you how to control the position of a servo witch an Arduino board and a desktop app developed in Java langauage.

This is a non-rigurous English translation for an article in my personal website: https://jjosemayorga.com/controlando-un-servomotor-desde-el-pc/


You can find this and many other interesting projects in my website and my social media.

🌐 https://jjosemayorga.com/

Twitter ► https://twitter.com/jjosemayorga

Instagram ► https://www.instagram.com/jjosemayorga/

Facebook ► https://www.facebook.com/jjosemayorgau

Youtube ► https://www.youtube.com/@jjosemayorga

TikTok ► https://www.tiktok.com/@jjosemayorga

Supplies

For this project you will need:

Wire the Components All Together

esquema_bb-980x765.png

In order to make the whole setup work, you just need to wire all the components in the way I show you in this picture.

If you need further explanation on how each element works or why I use them that way, you just need to visit the article on my website and get some instruction on it (it's in Spanish but, if you are not fluent in that language, Google translator will do the job 😉).

Load the Arduino Code

As for the Arduino part, I provide you the Arduino code I've used.

It's a pretty simple of the use of serial communication. Should you need to learn the very basics of this, let me address you again to the article on my website.

Downloads

Build the Java App

lightOFF.jpg
lightOFF.png
lightON.jpg
lightON.png
servom_png.png

Here you will find the Java code.

package servomotorBT;
 
import java.awt.*;
import java.awt.event.*;
 
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.metal.MetalSliderUI;
 
 
import java.io.*;
 
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Enumeration;
 
public class servoBT implements SerialPortEventListener
{
    int int_posicion=90;
    String str_posicion="90";
    JFrame marco=new JFrame("Control de servo");
    JLabel titulo=new JLabel("<html><font size=10 color=blue>Control de servo por puerto serie</font></html>");
    servomotor SV1=new servomotor(int_posicion);
    JLabel lbl_puerto=new JLabel("Puerto de conexión:");
    String[] str_puerto={"COM1","COM2","COM3","COM4","COM5","COM6","COM7","COM8","COM9","COM10","COM11","COM12","COM13","COM14","COM15","COM16","COM17","COM18","COM19","COM20","COM21","COM22","COM23","COM24","COM25","COM26"};
    JComboBox cmb_puerto=new JComboBox(str_puerto);
    JLabel lbl_baudrate=new JLabel("Baud Rate:");
    String[] str_baudrate={"4800","9600","19200","38400","57600","115200","234000","460800","921600","1382400"};
    JComboBox cmb_baudrate=new JComboBox(str_baudrate);
    JButton btn_conectar=new JButton("Conectar");
    JButton btn_desconectar=new JButton("Desconectar");
    JLabel lbl_conectar=new JLabel(new ImageIcon("lightOFF.png"));
    JTextField txt_posicion=new JTextField("90");
    JSlider sld_posicion=new JSlider(0,179);
    JTextField txt_noticias=new JTextField();
     
    /** The output stream to the port */
    private OutputStream output = null;
    private BufferedReader input;
    SerialPort serialPort;
    private String PORT_NAME = "COM1";
    /** Milliseconds to block while waiting for port open */
    private static final int TIME_OUT = 2000;
    /** Default bits per second for COM port. */
    private static int DATA_RATE = 9600;
 
     
     
    servoBT()
    {
        marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        marco.setIconImage(Toolkit.getDefaultToolkit().createImage("servom_png.png"));
        marco.setResizable(false);
        GridBagLayout gridbag=new GridBagLayout();
        GridBagConstraints gbc=new GridBagConstraints();
        marco.setLayout(gridbag);
        gbc.insets=new Insets(5,20,5,20);
        gbc.gridx=0;
        gbc.gridy=0;
        gbc.gridwidth=6;
        gbc.gridheight=1;
        marco.add(titulo,gbc);
        gbc.gridx=0;
        gbc.gridy=1;
        gbc.gridwidth=2;
        gbc.gridheight=4;
        SV1.setBackground(Color.cyan);
        SV1.setSize(400,400);
        marco.add(SV1,gbc);
        gbc.gridx=2;
        gbc.gridy=1;
        gbc.gridwidth=1;
        gbc.gridheight=1;
        gbc.weighty=0.5;
        gbc.anchor = GridBagConstraints.SOUTH;
        marco.add(lbl_puerto,gbc);
        gbc.gridx=3;
        gbc.gridy=1;
        gbc.gridwidth=1;
        gbc.gridheight=1;
        gbc.fill=GridBagConstraints.HORIZONTAL;
        cmb_puerto.addItemListener(new PORTlistener());
        marco.add(cmb_puerto,gbc);
        gbc.gridx=2;
        gbc.gridy=2;
        gbc.gridwidth=1;
        gbc.gridheight=1;
        gbc.fill=GridBagConstraints.NONE;
        gbc.weighty=0.5;
        gbc.anchor = GridBagConstraints.NORTH;
        marco.add(lbl_baudrate,gbc);
        gbc.gridx=3;
        gbc.gridy=2;
        gbc.gridwidth=1;
        gbc.gridheight=1;
        cmb_baudrate.addItemListener(new BRlistener());
        marco.add(cmb_baudrate,gbc);
        gbc.gridx=4;
        gbc.gridy=1;
        gbc.gridwidth=1;
        gbc.gridheight=1;
        gbc.anchor = GridBagConstraints.SOUTH;
        gbc.fill=GridBagConstraints.HORIZONTAL;
        btn_conectar.setName("conectar");
        btn_conectar.addMouseListener(new Conectar());
        marco.add(btn_conectar,gbc);
        gbc.gridx=4;
        gbc.gridy=2;
        gbc.gridwidth=1;
        gbc.gridheight=1;
        gbc.anchor = GridBagConstraints.NORTH;
        gbc.fill=GridBagConstraints.HORIZONTAL;
        btn_desconectar.setName("desconectar");
        btn_desconectar.addMouseListener(new Desconectar());
        marco.add(btn_desconectar,gbc);
        gbc.gridx=5;
        gbc.gridy=1;
        gbc.gridwidth=1;
        gbc.gridheight=2;
        gbc.fill=GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.CENTER;
        marco.add(lbl_conectar,gbc);
        gbc.gridx=2;
        gbc.gridy=3;
        gbc.gridwidth=4;
        gbc.gridheight=1;
        gbc.weighty=1.0;
        txt_posicion.setPreferredSize( new Dimension( 200, 50 ) );
        txt_posicion.setHorizontalAlignment(JTextField.CENTER);
        txt_posicion.setEditable(false);
        txt_posicion.setBackground(Color.white);
        Font font1 = new Font("SansSerif", Font.BOLD, 30);
        txt_posicion.setFont(font1);
        marco.add(txt_posicion,gbc);
        gbc.gridx=2;
        gbc.gridy=4;
        gbc.gridwidth=4;
        gbc.gridheight=1;
        sld_posicion.setMajorTickSpacing(20);
        sld_posicion.setMinorTickSpacing(5);
        sld_posicion.setPaintTicks(true);
        sld_posicion.setPaintLabels(true);
        sld_posicion.setValue(90);
        gbc.fill=GridBagConstraints.HORIZONTAL;
        sld_posicion.addChangeListener(new SliderListener());
        sld_posicion.addMouseListener(new SliderMListener());
        marco.add(sld_posicion,gbc);
        gbc.gridx=0;
        gbc.gridy=5;
        gbc.gridwidth=6;
        gbc.gridheight=1;
        gbc.fill=GridBagConstraints.HORIZONTAL;
        txt_noticias.setEditable(false);
        txt_noticias.setBackground(Color.white);
        marco.add(txt_noticias,gbc);
         
        marco.pack();
        marco.setLocationRelativeTo(null);
        marco.setVisible(true);
         
    }
     
    class SliderListener implements ChangeListener
    {
 
        @Override
        public void stateChanged(ChangeEvent e)
        {
            int_posicion=sld_posicion.getValue();
            str_posicion=String.valueOf(int_posicion);
            txt_posicion.setText(str_posicion);
            SV1.renovar(int_posicion);
            txt_noticias.setText("Posición enviada: "+str_posicion);
            sendData(str_posicion);
        }
         
    }
     
    class SliderMListener extends MouseAdapter
    {
        public void mousePressed(MouseEvent e)
        {
             Point p = e.getPoint();
                double percent = p.x / ((double) sld_posicion.getWidth());
                int range = sld_posicion.getMaximum() - sld_posicion.getMinimum();
                double newVal = range * percent;
                int result = (int)(sld_posicion.getMinimum() + newVal);
                sld_posicion.setValue(result);
        }
    }
     
    class BRlistener implements ItemListener
    {
 
        @Override
        public void itemStateChanged(ItemEvent evt)
        {
            // TODO Auto-generated method stub
             JComboBox cb = (JComboBox) evt.getSource();
             String str_DATA_RATE = (String) cb.getSelectedItem();
             DATA_RATE=Integer.parseInt(str_DATA_RATE);
             txt_noticias.setText("BaudRate cambiado a: "+str_DATA_RATE);
        }
         
    }
     
    class PORTlistener implements ItemListener
    {
 
        @Override
        public void itemStateChanged(ItemEvent evt)
        {
            // TODO Auto-generated method stub
             JComboBox cb = (JComboBox) evt.getSource();
             String str_PORT_NAME = (String) cb.getSelectedItem();
             PORT_NAME=str_PORT_NAME;
             txt_noticias.setText("Puerto cambiado a: "+str_PORT_NAME);
        }
         
    }
     
    class Conectar extends MouseAdapter
    {
        public void mousePressed(MouseEvent e)
        {
            Component aux=e.getComponent();
        }
        public void mouseReleased(MouseEvent e)
        {
            Component aux=e.getComponent();
            {
                if(aux.getName().equals("conectar"))
                {
                    initialize();
                }
            }
        }
    }
     
    class Desconectar extends MouseAdapter
    {
        public void mousePressed(MouseEvent e)
        {
            Component aux=e.getComponent();
        }
        public void mouseReleased(MouseEvent e)
        {
            Component aux=e.getComponent();
            {
                if(aux.getName().equals("desconectar"))
                {
                    serialPort.removeEventListener();
                    serialPort.close();
                    lbl_conectar.setIcon(new ImageIcon("lightOFF.png"));
                    txt_noticias.setText("Conexión cerrada");
                }
            }
        }
    }
     
    public void initialize()
    {
          
        CommPortIdentifier portId = null;
        Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
  
        // iterate through, looking for the port
        while (portEnum.hasMoreElements())
        {
            CommPortIdentifier currPortId = (CommPortIdentifier)
                    portEnum.nextElement();
  
            if (PORT_NAME.equals(currPortId.getName()))
            {
                portId = currPortId;
                break;
            }
        }
        if (portId == null)
        {
            System.out.println("Could not find COM port.");
            txt_noticias.setText("Conexión fallida");
            return;
        }
 
        try
        {
            // open serial port, and use class name for the appName.
            serialPort = (SerialPort) portId.open(this.getClass().getName(),
                    TIME_OUT);
 
            // set port parameters
            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();
 
            // add event listeners
            serialPort.addEventListener(this);
            serialPort.notifyOnDataAvailable(true);
            lbl_conectar.setIcon(new ImageIcon("lightON.png"));
            txt_noticias.setText("Conexión establecida");
        }
        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
            {
 
            }
            catch (Exception e)
            {
                System.err.println(e.toString());
            }
        }
    }
     
    private void sendData(String data)
    {
          
        try
        {
            output.write(data.getBytes());
        } catch (IOException e) {
            showError("Error sending data");
            //System.exit(ERROR);
        }
    }
    private void showError(String errorMessage)
    {
        JOptionPane.showMessageDialog(marco,
                errorMessage,
                "Error",
                JOptionPane.ERROR_MESSAGE);
    }
     
    public static void main(String[] args)
    {
        try
        {
          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch(Exception e)
        {
          e.printStackTrace();
        }
        servoBT app=new servoBT();
    }
 
}


In order to create the dynamic graphic we will need to create an additional class that inherits from tha Canvas class.

package servomotorBT;
 
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
public class servomotor extends Canvas
{
    int pos;
     
    public servomotor(int posicion)
    {
        pos=posicion;
    }
     
    void renovar(int posicion)
    {
        pos=posicion;
        repaint();
    }
     
    public void paint(Graphics g)
    {
        g.setColor(Color.black);
        g.fillOval(50, 50, 300, 300);
        Graphics2D g2 = (Graphics2D)g;
        g2.setStroke(new BasicStroke(16));
        g.setColor(Color.white);
        g.drawLine((int) (200-175*Math.cos(Math.toRadians(pos))), (int) (200-175*Math.sin(Math.toRadians(pos))), (int) (400-(200-175*Math.cos(Math.toRadians(pos)))), (int) (400-(200-175*Math.sin(Math.toRadians(pos)))));
    }
}


This code needs no frameworks, no libraries etc. It would even work just by compiling it in your CMD. As you will see, the interface is very simple.


I add as well the images required by the app. Place them in the right folder of the project.

Try the Whole Setup

Controlando un servo con aplicaci&oacute;n Java // Controlling a servo with a Java app

Here you have a demo of the project. Should you have any doubt or difficulty to reach an optimal result, you can contact me.