Showing posts with label Arduino Mega 2560. Show all posts
Showing posts with label Arduino Mega 2560. Show all posts

Thursday, August 7, 2014

Using JFreeChart to Show Arduino Data

Hi All,

In the previous tutorial I showed you how we can develop a simple chart application using JFreeChart. Now let's do something interesting with that. We are going to read some data from a Arduino and show that in a java chart. We are using the Java RxTx library for communication and JFreeChart for displaying the chart. Lets' start then.

First we will write a simple application that would send some random data from Arduino. There are situations where you have to send some sensor values for processing in a Java application. So here I'm trying to send some values that will appear like some sensor values.

float sensor_values[3]; //declare an arrary of 3 float values
float val_1,val_2,val_3; //declare 3 sensor values

void setup()
{
  Serial.begin(9600); //Start serial
  
  // Generate 3 random numbers between -100 and +100
  val_1 = random(-100,100); 
  val_2 = random(-100,100);
  val_3 = random(-100,100);
  
}

void loop()
{
  //if any value is equal to 100 start again from -100  
  if(val_1 >= 100){
    val_1 = -100;
  }
  else{
    val_1++;
  }
  
  if(val_2 >= 100){
    val_2 = -100;
  }
  else{
    val_2++;
  }
  
  if(val_3 >= 100){
      val_3 = -100;
  }  
  else{
    val_3++;
  }
  
  // Assign the values to array
  sensor_values[0] = val_1;
  sensor_values[1] = val_2;
  sensor_values[2] = val_3;
  
  //call the write sensor values function to write the values to serial port
  writeSensorValues(sensor_values);
}

//Method that will write the values to the serial port
void writeSensorValues(float values [])
{
  Serial.print("STX,"); //STX is used to identify the start of the string
  for(int i = 0 ; i < 3 ; i++){
    Serial.print(values[i]);
    Serial.print(","); // Seperate each value with ',' to identify them seperately
  }
  Serial.println("ETX"); //ETX is used to identify the end of the string
}

Now the Arduino code is complete. You can upload this code to your Arduino and check the output using the Serial Monitor.
Our next step is to write the Java Program that will read from the Arduino and display that data in a chart. I will get the help of the tutorials on Java RxTx for Serial Communication and JFree Chart tutorial to do this. I have described how to add the RxTx and JFreeChart libraries to the project in the above tutorials.

First create a class named 'SerialChart.java' and extend it from the ApplicationFrame class and implement the SerialPortEventListener class. Then add the constructor and add the unimplemented methods.



Now let's declare the variables that we need to use.

 private TimeSeriesCollection timeSeriesCollection; // Collection of time series data
 private XYDataset xyDataset; // dataset that will be used for the chart
 private TimeSeries seriesX; // X series data
 private TimeSeries seriesY; // Y series data
 private TimeSeries seriesZ; // X series data
 
 private BufferedReader input; // input reader
 private OutputStream output; //output reader
 private SerialPort serialPort; // serial port object
 
 private String [] PORT_NAMES = {"COM7"}; // available ports

Then let's start with a method that will initialize the serial port connection.

private void initializeSerial()
 {
  CommPortIdentifier portId = null;
  Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
  
  while(portEnum.hasMoreElements())
  {
   CommPortIdentifier currentPortIdentifier = (CommPortIdentifier)portEnum.nextElement();
   for(String portName : PORT_NAMES)
   {
    if(currentPortIdentifier.getName().equals(portName))
    {
     portId = currentPortIdentifier;
     break;
    }
   }   
  }
  
  if(portId == null)
  {
   System.out.println("Port not found");
   return;
  }
  
  try {
   
   serialPort = (SerialPort)portId.open(this.getClass().getName(), 2000);
   serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
   
   input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
   output = serialPort.getOutputStream();
   
   serialPort.addEventListener(this);
   serialPort.notifyOnDataAvailable(true);
   
  } catch (Exception e) {
   System.err.println("Initialization failed : " + e.toString());
  }
 }

Now let's create the method to return a chart object.

 private JFreeChart createChart() {

        JFreeChart chart = ChartFactory.createTimeSeriesChart(
            "Sensor Data Display",  // title
            "Time",             // x-axis label
            "Sensor Value",   // y-axis label
            timeSeriesCollection,            // data
            true,               // create legend?
            true,               // generate tooltips?
            false               // generate URLs?
        );

        chart.setBackgroundPaint(Color.white);

        XYPlot plot = (XYPlot) chart.getPlot();

        DateAxis axis = (DateAxis) plot.getDomainAxis();
        axis.setAutoRange(true);
  axis.setFixedAutoRange(60000.0);

        return chart;
 }

We can complete the constructor now.

public SerialChart(String title) {
  super(title);
  
  initializeSerial();
  
  timeSeriesCollection = new TimeSeriesCollection();
  seriesX = new TimeSeries("SensorX");
  seriesY = new TimeSeries("SensorY");
  seriesZ = new TimeSeries("SensorZ");
  
  timeSeriesCollection.addSeries(seriesX);
  timeSeriesCollection.addSeries(seriesY); 
  timeSeriesCollection.addSeries(seriesZ);
  
  JFreeChart chart = createChart();
  ChartPanel chartPanel = new ChartPanel(chart);
  chartPanel.setFillZoomRectangle(true);
  chartPanel.setMouseWheelEnabled(true);
  chartPanel.setPreferredSize(new java.awt.Dimension(1000,500));
  setContentPane(chartPanel);
 }

Next we have to complete the serialEvent method so that it will respond to the data received from Arduino.


 @Override
 public synchronized void serialEvent(SerialPortEvent event) {
  if(event.getEventType() == SerialPortEvent.DATA_AVAILABLE)
  {
   try
   {
    String inputLine = input.readLine();
    String [] inputValues = inputLine.split(",");
    
    if(inputValues[0].equals("STX") && inputValues[inputValues.length-1].equals("ETX"))
    {
     float in_x = new Float(inputValues[1]).floatValue();
     float in_y = new Float(inputValues[2]).floatValue();
     float in_z = new Float(inputValues[3]).floatValue();
     
     this.timeSeriesCollection.getSeries(0).add(new Millisecond(),in_x);
     this.timeSeriesCollection.getSeries(1).add(new Millisecond(),in_y);
     this.timeSeriesCollection.getSeries(2).add(new Millisecond(),in_z);
    }
    
    System.out.println(inputLine);
   }
   catch(Exception ex)
   {
    ex.printStackTrace();
   }
  }
 }

We also have to write a method to properly close the serial port event.

public synchronized void close()
 {
  if(serialPort != null)
  {
   serialPort.removeEventListener();
   serialPort.close();
  }
 }

Finally it's the main method to bring everything together.

 public static void main(String[] args) {

  SerialChart serialChartDemo = new SerialChart("Time Series Chart Demo");
        serialChartDemo.pack();
        RefineryUtilities.centerFrameOnScreen(serialChartDemo);
        serialChartDemo.setVisible(true);

    }

Now run the application and see the results :-). You'll get an output like this.


Following is the complete code. 

package com.dc.rxtxjfreechart;

import java.awt.Color;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Enumeration;

import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.Millisecond;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

public class SerialChart extends ApplicationFrame implements SerialPortEventListener {

 private TimeSeriesCollection timeSeriesCollection; // Collection of time series data
 private XYDataset xyDataset; // dataset that will be used for the chart
 private TimeSeries seriesX; // X series data
 private TimeSeries seriesY; // Y series data
 private TimeSeries seriesZ; // X series data
 
 private BufferedReader input; // input reader
 private OutputStream output; //output reader
 private SerialPort serialPort; // serial port object
 
 private String [] PORT_NAMES = {"COM7"}; // available ports
 
 public SerialChart(String title) {
  super(title);
  
  initializeSerial();
  
  timeSeriesCollection = new TimeSeriesCollection();
  seriesX = new TimeSeries("SensorX");
  seriesY = new TimeSeries("SensorY");
  seriesZ = new TimeSeries("SensorZ");
  
  timeSeriesCollection.addSeries(seriesX);
  timeSeriesCollection.addSeries(seriesY); 
  timeSeriesCollection.addSeries(seriesZ);
  
  JFreeChart chart = createChart();
  ChartPanel chartPanel = new ChartPanel(chart);
  chartPanel.setFillZoomRectangle(true);
  chartPanel.setMouseWheelEnabled(true);
  chartPanel.setPreferredSize(new java.awt.Dimension(1000,500));
  setContentPane(chartPanel);
 }

 @Override
 public synchronized void serialEvent(SerialPortEvent event) {
  if(event.getEventType() == SerialPortEvent.DATA_AVAILABLE)
  {
   try
   {
    String inputLine = input.readLine();
    String [] inputValues = inputLine.split(",");
    
    if(inputValues[0].equals("STX") && inputValues[inputValues.length-1].equals("ETX"))
    {
     float in_x = new Float(inputValues[1]).floatValue();
     float in_y = new Float(inputValues[2]).floatValue();
     float in_z = new Float(inputValues[3]).floatValue();
     
     this.timeSeriesCollection.getSeries(0).add(new Millisecond(),in_x);
     this.timeSeriesCollection.getSeries(1).add(new Millisecond(),in_y);
     this.timeSeriesCollection.getSeries(2).add(new Millisecond(),in_z);
    }
    
    System.out.println(inputLine);
   }
   catch(Exception ex)
   {
    ex.printStackTrace();
   }
  }
 }
 
 private void initializeSerial()
 {
  CommPortIdentifier portId = null;
  Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
  
  while(portEnum.hasMoreElements())
  {
   CommPortIdentifier currentPortIdentifier = (CommPortIdentifier)portEnum.nextElement();
   for(String portName : PORT_NAMES)
   {
    if(currentPortIdentifier.getName().equals(portName))
    {
     portId = currentPortIdentifier;
     break;
    }
   }   
  }
  
  if(portId == null)
  {
   System.out.println("Port not found");
   return;
  }
  
  try {
   
   serialPort = (SerialPort)portId.open(this.getClass().getName(), 2000);
   serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
   
   input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
   output = serialPort.getOutputStream();
   
   serialPort.addEventListener(this);
   serialPort.notifyOnDataAvailable(true);
   
  } catch (Exception e) {
   System.err.println("Initialization failed : " + e.toString());
  }
 }

 private JFreeChart createChart() {

        JFreeChart chart = ChartFactory.createTimeSeriesChart(
            "Sensor Data Display",  // title
            "Time",             // x-axis label
            "Sensor Value",   // y-axis label
            timeSeriesCollection,            // data
            true,               // create legend?
            true,               // generate tooltips?
            false               // generate URLs?
        );

        chart.setBackgroundPaint(Color.white);

        XYPlot plot = (XYPlot) chart.getPlot();

        DateAxis axis = (DateAxis) plot.getDomainAxis();
        axis.setAutoRange(true);
  axis.setFixedAutoRange(60000.0);

        return chart;
 }

 public synchronized void close()
 {
  if(serialPort != null)
  {
   serialPort.removeEventListener();
   serialPort.close();
  }
 }
 
 public static void main(String[] args) {

  SerialChart serialChartDemo = new SerialChart("Time Series Chart Demo");
        serialChartDemo.pack();
        RefineryUtilities.centerFrameOnScreen(serialChartDemo);
        serialChartDemo.setVisible(true);

    }
}




Hope that helps. Thank You. :-) 

Saturday, August 2, 2014

Using Java RxTx library for Serial Communication With Arduino - Part 2

Hi All,

In the previous post I showed you how you can use the Java RxTx library to find the Arduino connected COM port. Now let's do something useful. We can use this for reading values sent from the Arduino. With the values, we can play around and do whatever we like. In this post I'm using the code provided by Arduino.

First let's write a tiny Arduino program that prints some strings to Serial.



Then lets use the code provided by Arduino for reading values from Arduino. So here it is. I have just modified the code to split the chunks from the input string. (Line 81)



So that it.

Hope it would help.

Thank you. :-)




Using Java RxTx library for Serial Communication With Arduino - Part 1

Hi All,

Today I'm going to show you how you can use the Java RxTx library for Serial Communication with Arduino. This small java program is just to identify from which port your Arduino is connected to the PC. So this will be a good start if you are going to use RxTx library with Arduino. 

First you have to download the RxTx library from one of these locations. 
I used the link 1 to get the library for Windows x64. You can download x86 or x64 version according to your Operating System. 

Now we have to install RxTx in our program. You can do this in two ways. Both of them are easy, lets try the first one. I'm doing this with eclipse. 

First create your project in eclipse. 


Add a new class. I will name it "CommPortTest.java"


























Now lets add the RxTx library to the project. Extract the downloaded file and add it to the project using Right Click the Project -> Build Path -> Configure Build Path -> Libraries -> Add External JARs -> OK




















































Now Copy the two dll files (rxtxParallel.dll, rxtxSerial.dll) from the extracted library and paste it to the project folder. 


















Now you are ready for coding. So use the following code. 


Now Run the program. My Arduino was connected to COM7 and here's the output. 








You can check the Part 2 here

Hope this was helpful. 

Thank You. :-) 

Reference : 



Saturday, July 12, 2014

MPU6050 (GY-521 Breakout) + Arduino Mega 2560 Accelerometer and Gyroscope Application

Hi All,

I’m going to show you today how we can use the GY-521 Breakout with the Arduino Mega 2560 to get the readings from the sensor.

First I have to say that, I am totally new to Arduino and I have a limited knowledge in working with the registers and all the deep stuff. I’m trying to learn them and yes, this will be a beginning. J

So first let me show you what I have already bought.
First GY-521 Breakout for MPU-6050

 

Let me provide you some brief introduction about this product.
The InvenSense MPU-6050 sensor contains a MEMS accelerometer and a MEMS gyro in a single chip. It is very accurate, as it contains 16-bits analog to digital conversion hardware for each channel. Therefor it captures the x, y, and z channel at the same time.
- Chip: MPU-6050
- Power supply: 3.5V (But as there is a voltage regulator on the breakout board, you can use 5V directly)
- Communication mode: standard IIC communication protocol
- Chip built-in 16bit AD converter, 16bit data output
- Gyroscopes range: +/- 250 500 1000 2000 degree/sec
- Acceleration range: +/- 2g, +/- 4g, +/- 8g, +/- 16g
MPU-6050 Datasheet can be found here. Register map can be found here
Here is the schematic of GY-521



Now we have to get the Arduino Mega 2560 Board.



All the information related to this product can be found here.
So we have our items and the next important thing is to hookup these two together. Note the wiring is different for Arduino UNO. This wiring is for Arduino Mega 2560.



Here the connections are
GY-521                                  Arduino Mega
VCC                                        3.3V or 5V
GND                                      GND
SCL                                         Pin 21 (SCL)
SDA                                        Pin 20 (SDA)
INT                                         Pin 2 (Interrupt 0) – for more interrupt pins in Arduino click here


Now for the program. As we have a lot of resources regarding the usage of Arduino, let’s try the code from them (Although I had to spend several hours to work with them :P ).

First let’s try to find whether our device is connected with the Arduino. For that we can use the I2C Scanner code by Krodal to find out the connected I2C devices to Arduino. You can find the code here
Also following is the code. Compile the code and upload it to Arduino. Open the serial monitor and reset the Arduino.



It will find your GY-521 at the address 0x68 or 0x69. If it doesn’t find the IMU at that location, there might be an issue with your wiring. Please check it again. 


Now we can use the Krodal’s next code to get the raw outputs from the sensor. Krodal’s sketch can be found here. Please scroll to the end of the page and you’ll be able to find the code. Also I’ll be posting it here.


Here's the output.


Now we are ready to try the code from Jeff Rowberg. Download the I2C library from github. Here’s the link.

Now unzip the file and find the Arduino folder. Copy the I2Cdev and MPU6050 libraries to your Arduino libraries located at C:\Program Files (x86)\Arduino\libraries.



Now you are ready to use the I2Cdev and MPU6050 libraries. Locate example code in \Arduino\MPU6050\Examples\MPU6050_DMP6 and upload it to the Arduino. Now you will get the output from the Serial monitor. The output provides you the sensible values from the sensor unlike the raw outputs. Here Jeff has used the onboard Digital Motion Processor™ (DMP™) capable of processing complex 9-axis MotionFusion algorithms. You can find Jeff’s work here.






Now we can use the Processing demo provided by Jeff with the MPU6050 example. You can download Processing hereYou also have to install the toxiclib for Processing. You can find that here.

To install the toxic library just copy the contents of the zip file to the library folder in Pocessing projects directory.

Also create a folder named MPUTeapot in the Processing projects folder and copy the MPUTeapot.pde file to that folder from MPU6050 example code location.

Now you have to do the following changes in the Jeff’s MPU6050_DMF code.
  1. Comment the line  : #define OUTPUT_READABLE_YAWPITCHROLL
  2. Uncomment the line : #define OUTPUT_TEAPOT
  3. Now load the updated MPU6050_DMP code to Arduino.
  4. Run the MPUTeapot.pde in Processing
  5. You’ll see the small plane moving
So hope this would help someone. 
Thank You.