-3

I am trying to make Arduino and Java communicate with each other. I am using Eclipse. What my goal is to use the ArrayList I made in Java and have it sent to Arduino for it to use. I have been trying for days and can't seem to get this simple task to work. I want to be able to have the Java's ArrayList I created and have it sent to Arduino so then I can use the values of the ArrayList to make the Servo move a certain way. Here is what I have so far Arduino:

#include <Servo.h>
Servo servol;
int pos1=0;
int pos2=0;
int pos3=0;
int pos4=0;
int pos5=0;
int pos6=0;
int pos7=0;
int pos8=0;
int pos9;
int pos10=0;

void setup() {
  servol.attach(9);
  Serial.begin(9600);

  pos1=18;
  if(pos1==18){
    servol.write(18);
    Serial.println("The color is Red");
    delay(10000);
    servol.write(1);
  }
  else if(pos2==36){
    servol.write(36);
    Serial.println("The color is Orange");
    delay(10000);
    servol.write(1);
  }
  else if(pos3==54){
    servol.write(54);
    Serial.println("The color is Green");
    delay(10000);
    servol.write(1);
  }
  else if(pos4==72){
    servol.write(72);
    Serial.println("The color is Blue");
    delay(10000);
    servol.write(1);
  }
  else if(pos5==90){
    servol.write(90);
    Serial.println("The color is Purple");
    delay(10000);
    servol.write(1);
  }
  else if(pos6==108){
    servol.write(108);
    Serial.println("The color is Pink");
    delay(10000);
    servol.write(1);
  }
  else if(pos7==126){
    servol.write(126);
    Serial.println("The color is Red");
    delay(10000);
    servol.write(1);
  }
  else if(pos8==144){
    servol.write(144);
    Serial.println("The color is Black");
    delay(10000);
    servol.write(1);
  }
  else if(pos9==162){
    servol.write(162);
    Serial.println("The color is Grey");
    delay(10000);
    servol.write(1);
  }
  else if(pos10==180){
    servol.write(180);
    Serial.println("The color is White");
    delay(10000);
    servol.write(1);
  }
  else{
    Serial.println("Error");
    delay(10000);
    servol.write(0);
  }
}

void loop() {
}

I want to use this Java code and have it communicate with Arduino so I can use real data:

package MATLAB;

import javax.swing.*;
import java.io.IOException;

public class Main {

public static void main(String[] args) throws IOException {
    Tabs tp = new Tabs(); //creates the tabs to hold both figures
    tp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //the code ends as soon as the tabs are closed out of
    tp.pack(); //basically sets it so the GUI displays full screen
    tp.setVisible(true); //displays the GUI

    int maxColorIndex = ColorProportions.retrieveMaxColor(); //uses the "retrieveMaxColor" method in the "ColorProportions" class to get the index that has the greatest proportion
    /* The above line of code will always be equal to a number 0 through 9, since we are only using ten colors for the color wheel
    0 is White
    1 is Red (combination of DarkRed, Red, and LightRed)
2 is Orange (combination of DarkOrange, Orange, and LightOrange)
3 is Yellow (combination of DarkYellow, Yellow, and LightYellow)
4 is Green (combination of DarkGreen, Green, and LightGreen)
5 is Blue (combination of DarkSkyBlue, SkyBlue, LightSkyBlue, DarkBlue, Blue, and LightBlue)
6 is Purple (combination of DarkPurple, Purple, and LightPurple)
7 is Pink (combination of DarkPink, Pink, LightPink, DarkHotPink, HotPink, and LightHotPink)
8 is Grey (combination of DarkGrey, Grey, and LightGrey)
9 is Black
So if "maxColorIndex" is 7, that means the servo should point to the "Pink" color on the color wheel
     */
    }
}

           package MATLAB;


    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.KeyEvent;

    public class Tabs extends JFrame {
        public Tabs() {

    setTitle("Tabbed Pane"); //title of the figure
    JTabbedPane jtp = new JTabbedPane(); //creates the area the tabs will reside within
    getContentPane().add(jtp); //adds the area created above to an arraylist of areas (size 1 because we only want one section of tabs)
    ImageIcon oImg = new ImageIcon("C:\\Users\\InGodWeTrush\\Desktop\\MATLAB\\imageLogo.png"); //creates the logo that will represent the first tab
    Image image = oImg.getImage(); //changes the ImageIcon into an Image so we can scale it to an appropriate size
    Image newimg = image.getScaledInstance(50, 40,  java.awt.Image.SCALE_SMOOTH); // scale the logo in the smooth way
    oImg = new ImageIcon(newimg);  // transform it back into an ImageIcon
    ImageIcon mImg = new ImageIcon("C:\\Users\\InGodWeTrush\\Desktop\\MATLAB\\barLogo.png"); //creates the logo that will represent the second tab
    Image image2 = mImg.getImage(); //changes the ImageIcon into an Image so we can scale it to an appropriate size
    Image newimg2 = image2.getScaledInstance(50, 40, java.awt.Image.SCALE_SMOOTH); // scale it the smooth way
    mImg = new ImageIcon(newimg2);  // transform it back into an ImageIcon
    JLabel label1 = new JLabel(new ImageIcon("C:\\Users\\InGodWeTrush\\Desktop\\MATLAB\\MainFigure.png")); //creates the image we actually want to see when clicking the first tab
    JLabel label2 = new JLabel(new ImageIcon("C:\\Users\\InGodWeTrush\\Desktop\\MATLAB\\BarFigure.png")); //creates the image we actually want to see when clicking the second tab
    JPanel jp1 = new JPanel(); //creates a panel where we will put the pictures, color lines, and 3D cluster plot
    JPanel jp2 = new JPanel(); //creates a panel where we will put the bar graphs
    jp1.add(label1); //adds the actual image of the pictures, color lines, and 3D cluster plot to the panel
    jp2.add(label2); //adds the actual image of the bar graphs to the panel
    jtp.addTab("",oImg, jp1); //actually creates the individual first tab
    jtp.setMnemonicAt(0, KeyEvent.VK_1); //if the first tab is clicked, then the first panel will show
    jtp.addTab("",mImg, jp2); //actually creates the individual second tab
    jtp.setMnemonicAt(1, KeyEvent.VK_2); //if the second tab is clicked, then the second panel will show
        }
    }

package MATLAB;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

/**
 * Created by Shane on 12/1/2017.
 */
public class ColorProportions {
    private static String line = null; //String that will represent every individual line of text file
    private static ArrayList<Double> colors = new ArrayList<>(); //ArrayList to hold all color proportions acquired from text file
    private static int maxColorIndex; //int that will hold the final index that holds the max proportion

    public static int retrieveMaxColor() throws IOException {
        File txtFile = new File("C:\\Users\\InGodWeTrush\\Desktop\\MATLAB\\propsArray.txt"); //grab the text file
        FileReader reader = new FileReader(txtFile); //read the text file
        BufferedReader bufferedReader = new BufferedReader(reader); //read the text file in such a way we can loop through the individual lines
        while ((line = bufferedReader.readLine()) != null) { //while there is another line in the text file to read
            colors.add(Double.parseDouble(line)); //add that line into the color proportions ArrayList (there are 32 lines to represent the 32 colors)
        }
        double propSum = 0; //double that will hold the sum of all color props we must combine; so this sum will hold DarkRed, Red, and LightRed to represent all the Reds
        int count = 0; //integer to determine when all the color props we must combine are added together
        int nextIndex = 1; //the index we want to put the new proportion within (goes from 1 to 8 because 0 is White in the old and new array and 9 is black in the old and new array)
        for (int i = 0; i < colors.size(); i++) { //loops through every element of color props array (there are 32 elements)
            if ((i > 0 && i < 13) || (i > 18 && i < 22) || (i > 27 && i < 31)) { //this if statement gets the color props combination for colors that only have three to combine; so DarkRed, Red, and LightRed proportions are all combined to make Red here
                propSum += colors.get(i); //adds up the proportions that must be combined, so if DarkRed = 20, Red = 10, and LightRed = 15, then the new array will have Red = 45
                count++; //counts up so we know we already did one of the proportions that must be combined
                if (count == 3) { //once all three are combined
                    colors.set(nextIndex, propSum); //set the next index in the new array equal to the combined proportions; now that Red = 45, the second element in the array is equal to 45, and the first element is equal to the white proportion
                    count = 0; //resets this so we can move onto the next proportions that must be combined
                    propSum = 0; //reset this so that the next proportion combinations can properly be added together
                    nextIndex++; //increases the index that the combined color proportions are added to so we simply don't replace them; 0 is white, 1 is Red, 2 is Orange, etc.
                }
            }
            if ((i > 12 && i < 19) || (i > 21 && i < 28)) { //this if statement gets the color props combination for colors that have six to combine; so DarkSkyBlue, SkyBlue, LightSkyBlue, DarkBlue, Blue, and LightBlue proportions are all combined to make Blue here
                propSum += colors.get(i); //adds up the proportions that must be combined, so if DarkSkyBlue = 20, SkyBlue = 10, and LightSkyBlue = 3, DarkBlue = 1, Blue = 2, and LightBlue = 2 then the new array will have Blue = 38
                count++; //counts up so we know we already did one of the proportions that must be combined
                if (count == 6) { //once all six are combined
                    colors.set(nextIndex, propSum); //set the next index in the new array equal to the combined proportions; now that Blue = 38, the sixth element in the array is equal to 38
                    count = 0; //resets this so we can move onto the next proportions that must be combined
                    propSum = 0; //reset this so that the next proportion combinations can properly be added together
                    nextIndex++; //increases the index that the combined color proportions are added to so we simply don't replace them; 0 is white, 1 is Red, 2 is Orange, etc.
                }
            }
            if (i == 31) //if we are looking at the last element of the array (black)
                colors.set(9, colors.get(i)); //set it to the tenth element of the array, as we want the last element of our array to be 9 since we only have ten colors (0 to 9)
        }
        for (int i = 0; i < 22; i++) { //array was initially size 32, but now we only want it to be size 10, so we remove the uneeded elements 22 times since there are 22 of them
            colors.remove(10); //removes all of the extra elements that are no longer needed, so we only have the ten combined proportions
        }
        double max = 0; //double that will hold the largest percentage
        for (int i = 0; i < colors.size(); i++) { //loops through the 10 new and combined proportions
            if (colors.get(i) > max) { //if the element we are looking at has a greater proportion than any of the previous elements
                maxColorIndex = i; //then the index with the greatest proportion is now equal to this element
                max = colors.get(i); //the new max is equal to this element's proportion
            }
        }
        return maxColorIndex; //returns the max index; so if we have array [1, 5, 3, 1], then it will return "1" because 5 is the largest proportion and it is in the second index (after the zeroth index)
    }
}
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • Sorry not used to uploading on Stack. I am currently only looking for ways to comminucate JAVA and Arduino. Do you know any possible way to have it communicate with each other? This project has to involve using java –  Dec 03 '17 at 18:14
  • 1
    For starters, your question has too much code to be considered a [mcve]. Remove all the GUI components, as they are not necessary to read/send Arduino data – OneCricketeer Dec 03 '17 at 19:00
  • 1
    So, after days of research, it never occurred to you to search for "Java serial communication"? Because [this](https://stackoverflow.com/q/264277) is what you would find. – gre_gor Dec 04 '17 at 00:52
  • Have you been able to figure out how to do what you wanted to do? Was my suggestion of RXTX helpful? Let us know if you have any issues or if you need a different solution. – Keara Dec 05 '17 at 18:58

1 Answers1

1

You could try using the RXTX Java library to communicate over the serial port (where the Arduino plugs in to your computer.) The Arduino website provides some sample code to get you started. As long as you have the Arduino IDE installed, you automatically have RXTX. Save the following code in Eclipse as SerialTest.java and run it as an example. You may need to modify the PORT_NAMES of this sample to use the correct COM port that you are using.

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/ttyACM0", // Raspberry Pi
            "/dev/ttyUSB0", // Linux
            "COM3", // Windows
    };
    /**
    * A BufferedReader which will be fed by a InputStreamReader 
    * converting the bytes into characters 
    * making the displayed results codepage independent
    */
    private BufferedReader input;
    /** The output stream to the port */
    private OutputStream output;
    /** Milliseconds to block while waiting for port open */
    private static final int TIME_OUT = 2000;
    /** Default bits per second for COM port. */
    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 {
            // 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);
        } catch (Exception e) {
            System.err.println(e.toString());
        }
    }

    /**
     * This should be called when you stop using the port.
     * This will prevent port locking on platforms like Linux.
     */
    public synchronized void close() {
        if (serialPort != null) {
            serialPort.removeEventListener();
            serialPort.close();
        }
    }

    /**
     * Handle an event on the serial port. Read the data and print it.
     */
    public synchronized void serialEvent(SerialPortEvent oEvent) {
        if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
            try {
                String inputLine=input.readLine();
                System.out.println(inputLine);
            } 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");
    }
}
Keara
  • 589
  • 1
  • 6
  • 17
  • Better now, awesome! – Zabuzard Dec 04 '17 at 15:02
  • Is there way to fix the error "C:\Program Files (x86)\Java\jre1.8.0_101\lib\gnu.io.rxtx.SerialPorts IOException!" I have changed the port name to match the one that is used when you plug in the USB for arduino –  Dec 08 '17 at 16:31
  • I think you should ask a new question about that. – Keara Dec 08 '17 at 17:01