/* -------------- FIPEX Measurement on REXUS -----------------
*
* Rexus 15/16 Team MOXA Implementation
* Target: STM32F103RB
* Author: A. Schultze 2013
* Date : 22.07.2013
* Version: 0.9 (ALPHA)
*
*
* ------------------------------------------------------------- */
package BaseClasses;
import Main.Main;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.awt.BorderLayout;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.swing.JFrame;
//
public class SerialPort_Connector
{
private static DataHandler adc,temp,log,raw_comm;
private static CommPort commPort;
public static int stat_rx_packages=0;
public static int stat_tx_packages=0;
public static int stat_crc_err=0;
public static int stat_bytes_read=0;
private static boolean isConnected=false;
public SerialPort_Connector()
{
super();
}
public static void addDataHandler(DataHandler p_adc,DataHandler p_temp,DataHandler p_log, DataHandler p_raw_comm)
{
adc=p_adc;
temp=p_temp;
log=p_log;
raw_comm=p_raw_comm;
}
public static void disconnect(){
/* This function is buggy since it thinks there is still an IORequest. It is a rxtx bug. */
if ( commPort != null) {
try {
// close the i/o streams.
commPort.getInputStream().close();
commPort.getOutputStream().close();
} catch (IOException ex) {
// don't care
}
// Close the port.
commPort.close();
}
}
public static boolean isConnected(){
return isConnected;
}
public static void connect ( String portName, String baudRate) throws Exception
{
isConnected=true;
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
Main.log.addLine(".. connecting: "+portName);
if ( portIdentifier.isCurrentlyOwned() )
{
// System.out.println("Error: Port is currently in use");
Main.log.addLine("Error: Port is currently in use");
}
else
{
commPort = portIdentifier.open("jStation",2000);
if ( commPort instanceof SerialPort )
{
SerialPort serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(Integer.parseInt(baudRate),SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();
(new Thread(new SerialReader(in))).start();
(new Thread(new SerialWriter(out))).start();
}
else
{
log.addLine("Error: Only serial ports are handled by this example.");
}
}
}
/** */
public static class SerialReader implements Runnable
{
long tx_stats_bytes=0;
InputStream in;
public SerialReader ( InputStream in )
{
this.in = in;
}
public void run ()
{
byte[] buffer = new byte[1024];
int len = -1;
try
{
while ( ( len = this.in.read(buffer)) > -1 )
{
tx_stats_bytes=tx_stats_bytes+len;
// System.out.printf("XX(%d)",len); /* Raw Input */
// System.out.print(bytesToHex(buffer,len)); /* Raw Input in HEX */
// raw_comm.addString(bytesToHex(buffer,len));
for (int i=0; i<len; i++){PackageRetriever.add_byte(buffer[i]);stat_bytes_read++;}
}
}
catch ( IOException e )
{
e.printStackTrace();
}
}
}
/** */
public static class SerialWriter implements Runnable
{
OutputStream out;
public SerialWriter ( OutputStream out )
{
this.out = out;
}
public void run ()
{
try
{
int c = 0;
while ( ( c = System.in.read()) > -1 )
{
this.out.write(c);
}
}
catch ( IOException e )
{
e.printStackTrace();
}
}
}
public static void start ( String namePort, String baudRate )
{
try
{
(new SerialPort_Connector()).connect(namePort, baudRate);
}
catch ( Exception e )
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static int twosComp8(int complement){
/* Because Java reverts all the Data to signed in complement */
if(complement<0){return complement+256;}else{return complement;}
}
public static int twosComp32(int complement){
/* Because Java reverts all the Data to signed in complement */
if(complement<0){return complement+2^32;}else{return complement;}
}
public static String byteToHex(byte bytes) {
final char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char[] hexChars = new char[2];
int v;
for ( int j = 0; j < 2; j++ ) {
v = bytes & 0xFF;
hexChars[0] = hexArray[v >>> 4];
hexChars[1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
public static String bytesToHex(byte[] bytes) {
final char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char[] hexChars = new char[bytes.length * 2];
int v;
for ( int j = 0; j < bytes.length; j++ ) {
v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
public static String bytesToHex(byte[] bytes, int length) {
final char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char[] hexChars = new char[length * 2];
int v;
for ( int j = 0; j < length; j++ ) {
v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
private static class PackageRetriever{
public PackageRetriever(){
System.out.print("PackageRetriever constructor called");
}
static byte[] bytebuffer=new byte[32];
static int[] intbuffer=new int[32];
static int read_state=0;
static int bytes_read=0;
public static void add_byte(byte in){
//if(TwoWaySerialComm.byteToHex(in).equalsIgnoreCase("16")){System.out.print("FOUND A SYNC");}
raw_comm.addString(SerialPort_Connector.byteToHex(in));
if(in==0x16){
switch(read_state){
case 0: read_state=1;return;
case 1: read_state=2;bytes_read=0;raw_comm.addString("\nSYNC|");return;
case 2: read_state=3;break;
case 3: read_state=2; bytes_read=0;raw_comm.addString("\nRESYNC|"); return;
/* If the last Byte of CRC is also SYNC, it fails. Check if this is the last Byte! Fix 0.4% crc drop
On the other hand side it introduces a problem if 2 bytes were dropped
if(bytes_read!=24+2+1)
*/
}
}
/* Add byte to the buffer */
/* Note: The uC Values are all unsigned. On Java there is no unsigned type. When converting notice that! For u8,u16! */
if(read_state>=2){
intbuffer[bytes_read]=twosComp(in);
bytebuffer[bytes_read++]=in;
}
if(bytes_read==(4+24)&&(read_state>=2)){
read_state=0;
bytes_read=0;
raw_comm.addString("END|");
/* Step 1 - check the CRC */
SerialPort_Connector.stat_rx_packages++;
int crc_msg=(intbuffer[27])<<8 | intbuffer[28];
int crc_calc=crc16(bytebuffer,27);
if(crc_msg==crc_calc){
raw_comm.addString("|CRC_OK|");
/* enum MSG_BYTE {SYNC=0x16,
MSGID_ADC0=0xA0, 7 ADC1_0-6 x 2 Byte
MSGID_ADC1=0xA1, * ADC1_7-13 x 2 Byte
MSGID_ADC2=0xA2, * 4 ADC2_0-3 x 2 Byte
MSGID_ADC_CSV=0xAF, * -variable -
MSGID_TEMP0=0xB0, * 6 TEMP x 2 Byte
MSGID_TEMP1=0xB1, * -void -
MSGID_TEMP2=0xB2, * -void -
MSGID_TEMP_CSV=0xBF, * -variable -
MSGID_SENSORS=0xC0, * 3 Sens1-3 x 3 x 2 Byte
MSGID_HEATINGS=0xCA, * 3 Sens1-3 x 2 x 2 Byte
MSGID_POWERS=0xD0, * 3*2 Byte: U_bat|I_bat|I_rexus
MSGID_PRESSURE=0xDA, * 2*u16: Pressure VSP62|JUMO *
MSGID_STATUS0=0xE0, * TIME_LO, TIME_SYS, STATE, HATCH
MSGID_STATUS1=0xE1, * void *
MSGID_INFOSTRING=0x00 * - variable *
* TODO: At this point the packages have to be sorted and and read out.
* This should take place in another class which can be called here.
*/
/* But for TONIGHT - I want to read out the ADC RAW Values and
* draw the first values and draw them!
*/
if(intbuffer[0]==0xA0){
double[] value_buffer=new double[12];
value_buffer[0]=(double) (intbuffer[2]<<8|intbuffer[3]);
value_buffer[1]=(double) (intbuffer[4]<<8|intbuffer[5]);
value_buffer[2]=(double) (intbuffer[6]<<8|intbuffer[7]);
value_buffer[3]=(double) (intbuffer[8]<<8|intbuffer[9]);
value_buffer[4]=(double) (intbuffer[10]<<8|intbuffer[11]);
value_buffer[5]=(double) (intbuffer[12]<<8|intbuffer[13]);
value_buffer[6]=(double) (intbuffer[14]<<8|intbuffer[15]);
adc.AddData(value_buffer, 6);
/* This will write out all the RAW ADC Values for recovery later */
}
if(intbuffer[0]==0xA1){
double[] value_buffer=new double[12];
value_buffer[0]=(double) (intbuffer[2]<<8|intbuffer[3]);
value_buffer[1]=(double) (intbuffer[4]<<8|intbuffer[5]);
value_buffer[2]=(double) (intbuffer[6]<<8|intbuffer[7]);
value_buffer[3]=(double) (intbuffer[8]<<8|intbuffer[9]);
value_buffer[4]=(double) (intbuffer[10]<<8|intbuffer[11]);
value_buffer[5]=(double) (intbuffer[12]<<8|intbuffer[13]);
value_buffer[6]=(double) (intbuffer[14]<<8|intbuffer[15]);
adc.AddData(value_buffer, 6);
/* TODO: Must be sent into its own adc DataHandler */
/* This will write out all the RAW ADC Values for recovery later */
}
if(intbuffer[0]==0xB0){
double[] value_buffer=new double[12];
value_buffer[0]=(double) (intbuffer[2]<<8|intbuffer[3]);
value_buffer[1]=(double) (intbuffer[4]<<8|intbuffer[5]);
value_buffer[2]=(double) (intbuffer[6]<<8|intbuffer[7]);
value_buffer[3]=(double) (intbuffer[8]<<8|intbuffer[9]);
temp.AddData(value_buffer, 4);
/* Here we could do some conversion of the Temperature Elements from U16 to actual Temperatures according on the Temperature Values.
* for instance for the LM75 and the PT1000.
*/
}
if(intbuffer[0]==0xC0){
/* Package Code for SENSOR */
Main.sensors[0].u16_u= (intbuffer[2]<<8|intbuffer[3]);
Main.sensors[0].u16_i= (intbuffer[4]<<8|intbuffer[5]);
Main.sensors[0].gain=(intbuffer[6]);
Main.sensors[0].update();
Main.sensors[1].u16_u= (intbuffer[7]<<8|intbuffer[8]);
Main.sensors[1].u16_i= (intbuffer[9]<<8|intbuffer[10]);
Main.sensors[1].gain=(intbuffer[11]);
Main.sensors[1].update();
Main.sensors[2].u16_u= (intbuffer[12]<<8|intbuffer[13]);
Main.sensors[2].u16_i= (intbuffer[14]<<8|intbuffer[15]);
Main.sensors[2].gain=(intbuffer[16]);
Main.sensors[2].update();
}
if(intbuffer[0]==0xCA){
/* Package Code for HEATING */
Main.heating[0].u16_u= (intbuffer[2]<<8|intbuffer[3]);
Main.heating[0].u16_i= (intbuffer[4]<<8|intbuffer[5]);
Main.heating[0].update();
Main.heating[1].u16_u= (intbuffer[6]<<8|intbuffer[7]);
Main.heating[1].u16_i= (intbuffer[8]<<8|intbuffer[9]);
Main.heating[1].update();
Main.heating[2].u16_u= (intbuffer[10]<<8|intbuffer[11]);
Main.heating[2].u16_i= (intbuffer[12]<<8|intbuffer[13]);
Main.heating[2].update();
}
if(intbuffer[0]==0xD0){
/* Package Code for Power Information*/
Main.status.u16_u_bat= (intbuffer[4]<<8|intbuffer[5]);
Main.status.u16_i_bat=(intbuffer[2]<<8|intbuffer[3]);
Main.status.u16_i_rexus=(intbuffer[6]<<8|intbuffer[7]);
Main.status.update();
}
if(intbuffer[0]==0xDA){
/* Package Code for Pressure*/
Main.pressure[0].u16_u= (intbuffer[2]<<8|intbuffer[3]);
Main.pressure[0].getPressureVSP62(); /* Hatch 1 - VSP62 */
Main.pressure[1].u16_u= (intbuffer[4]<<8|intbuffer[5]);
Main.pressure[1].getPressureJUMO(); /* Hatch 2 - VSP62 */
}
if(intbuffer[0]==0xE0){
/* Package Code for Pressure*/
Main.status.Time_LO= (intbuffer[2]<<8|intbuffer[3]);
Main.status.Time_SYS=(intbuffer[4]<<8|intbuffer[5]);
Main.status.Status=(intbuffer[6]);
Main.status.Hatch=(intbuffer[7]);
/* This is the last package received. It will trigger a processing of writing out all the values in a structured way */
Main.window.dataupdate();
}
if(intbuffer[0]==0x00){
log.addString(new String(bytebuffer).substring(2, 2+24));
}
}else{log.addString("|CRC_ERR|"); SerialPort_Connector.stat_crc_err++;}
read_state=0;
}
}
static int crc16(final byte[] buffer, int length) {
int crc = 0xFFFF;
for (int j = 0; j < length ; j++) {
crc = ((crc >>> 8) | (crc << 8) )& 0xffff;
crc ^= ((buffer[j]) & 0xff);//byte to int, trunc sign
crc ^= ((crc & 0xff) >> 4);
crc ^= (crc << 12) & 0xffff;
crc ^= ((crc & 0xFF) << 5) & 0xffff;
}
crc &= 0xffff;
return crc;
}
}
public static void PackageSender8(byte msg_id, int msg1,int msg2,int msg3){
/* This function takes two 8 Bit Unsigned and one 32 bit unsigned and puts them into into 22 Byte Package */
OutputStream outStream;
try
{
outStream=commPort.getOutputStream();
byte[] bytebuffer=new byte[24];
bytebuffer[0]=msg_id;
bytebuffer[1]=(byte) ++stat_tx_packages;
bytebuffer[2]=(byte)msg1;
bytebuffer[3]=(byte)msg2;
bytebuffer[4]=(byte)(msg3 >>> 24);
bytebuffer[5]=(byte)(msg3 >>> 16);
bytebuffer[6]=(byte)(msg3 >>> 8);
bytebuffer[7]=(byte)(msg3);
int crc_calc=crc16(bytebuffer,18);
bytebuffer[18]=(byte) (crc_calc>>8);
bytebuffer[19]=(byte) (crc_calc);
outStream.write(0x16);
outStream.write(0x16);
outStream.write(bytebuffer,0,20);
}catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void PackageSender(byte msg_id, String msg){
/* This function takes 16 Byte Data and puts them into into 22 Byte Package */
OutputStream outStream;
try
{
outStream=commPort.getOutputStream();
byte[] bytebuffer=new byte[24];
bytebuffer[0]=msg_id;
bytebuffer[1]=(byte) ++stat_tx_packages;
System.arraycopy(msg.getBytes(), 0, bytebuffer, 2, msg.length());
int crc_calc=crc16(bytebuffer,18);
bytebuffer[18]=(byte) (crc_calc>>8);
bytebuffer[19]=(byte) (crc_calc);
outStream.write(0x16);
outStream.write(0x16);
outStream.write(bytebuffer,0,20);
SerialPort_Connector.stat_tx_packages++;
}catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
static int twosComp(int complement){
/* Because Java reverts all the Data to signed in complement */
if(complement<0){return complement+256;}else{return complement;}
}
static int crc16(final byte[] buffer, int length) {
int crc = 0xFFFF;
for (int j = 0; j < length ; j++) {
crc = ((crc >>> 8) | (crc << 8) )& 0xffff;
crc ^= ((buffer[j]) & 0xff);//byte to int, trunc sign
crc ^= ((crc & 0xff) >> 4);
crc ^= (crc << 12) & 0xffff;
crc ^= ((crc & 0xFF) << 5) & 0xffff;
}
crc &= 0xffff;
return crc;
}
}