Interfacing a Java Program
with
C++ I/O Routines
HumberCollege/Toronto
Technical Project: Elic 606
Thomas Shortt 823 947 437
Giovanni Bianchi 826 030 637
June 25, 2001
Table of Contents
Pg.#
Acknowledgments 1
Introduction ~ About Java 2
Hardware Portion .3
Costing and Reference . .6
About Assembler . ..7
Flow Chart of Assembly Code . .8
The C++ Coding . ...9
Writing the Java with Native Method ..10
Flow Chart for SimpleSimpleServer program .11
Steps in creating SimpleSimpleServer .12
Accessing the Java Member Variable ..14
The Main Method Implementation ..16
The Java Class Coding .17
Sending the Page or POSTing the Form ...19
Conclusion 21
Sources . .22
Figures
Fig 1.1 - Data Acquisition Hardware
Fig 1.2 - 5v Power Supply
Acknowledgments
This project would not be what it is without the
contributions of others.
Steve Wilton provided us a simple server which
was modified to provide the base to our Java class. He also helped with the
Borland interface, used to build the dynamic load library.
Tanya Davis was available for clarification of
Java language and programming issues. Exercise of language is the best way to
learn.
Along with the ever thorough Kelly Gray, the
above people of knowledge are Educational Assistance that inhabit N208 at
Humber College, most days.
Sam Flagiellos friend Mike also contributed by
shortening the process of FORM submission rationalization, during the
development of the paging part of the program.
Finally, I cannot forget Sahila Nalliah who leant her PCS
phone to the development of the project, and was in general very supportive of
this projects development.
Introduction
Firstly Joe Enekes suggestion was:
Interfacing a Java program with C-language or assembly language I/O routines.
Write, debug, and test a Java program that integrates existing assembly or C-language port I/O input/output routines. Demonstrate the functionality of your design by receiving a byte through the parallel port and displaying its value in a browser window.
Seed for your starting point can be found at web site:
http://java.sun.com/docs/books/tutorial/native1.1/stepbystep/index.html
Secondly there was the problem of the furnace quitting at the cottage, and how do we notice this if none are there to see and correct the potential problem.
Our aim in this project was from the start, to see if we could utilize our knowledge of electronics and learn enough of Java to allow us to firstly solve Joes challenge and if time allows, use java to access the internet and sent a message the alert us of a temperature condition.
Rather then describe all the ins and outs, we present what we found that works. This report describes the versatile circuit we developed, and the development of a Java program with native C++ interface. Included are the addresses of useful Sun Java sites that we found to be of use, as will as information that was developed to accommodate the environment found within the Humber College computing facilities.
We used Windows 95 et el. PCs w/ Borland C++ 5.02 & w/ jdk1.2.2 as the java on our C: drive.
Bye and large the program material is presented in the order of development and in hindsight the most educative presentation.
About JAVA:
Sun Microsystems conceptualized Java as a way to add dynamic content to WWW pages. It is based on C and C++. It is designed to be truly portable (to be platform independent). And best of all it is freely available from Sun at java.sun.com. It was first released to the public in 1995.
It should be pointed out here that it is not
customary to use conventional flow charts to describe Java classes. Dialogue is
used. We attempt to be concise and to the point, in our description. We attempt
the use the style of description found in java texts.
When real world data is acquired and
sent to be processed a data acquisition and signal-conditioning setup is
required. This consists of four
essential stages; a transducer, a signal conditioner, analog to digital converter
and a PC. A transducer is a device that
converts real world impulses such as acceleration, direction, speed, light
intensity etc. into electrical signals that can be used by the digital world. Once the transducer has produced an
electrical signal this signal will pass through a signal conditioning
stage. Signal conditioning modifies the
signal produced by the transducer to fit the specifications of the hardware and
software used. The signal conditioning
process can consist of amplification, filtering, isolation, etc. Next is the analog to digital conversion
stage, which converts the analog signal to the TTL signals required by the
PC. These TTL signals are sent to the
PC via the parallel port.
The real world data that was
gathered and process was atmospheric temperature. Temperature limits were set to 5ฐC to 40ฐC. An
LM35 (Appendix A) was used as the temperature sensor (transducer). The LM35 was setup in a Temperature
Sensor, Single Supply, -55ฐC to 150ฐC configuration. Using this setup will allow the LM35 to operate in a temperature
range of 55ฐC to 150ฐC.
According to the specification sheets the LM35 produced a voltage output
of .455v to .905v for the 5ฐC to 40ฐC range,
respectively.
A single source amplifier, KA358
(Appendix B), was used for signal conditioning section of the circuit. The voltage range generated by the LM35
(.455v to .905v) was amplified to a higher voltage range that could be applied
to the ADC. The KA358 was setup as a High
Input DC Differential Amplifier. A
gain was measure to be 3.05.
The analog voltage output from the
amplifier was then applied to an Analog to Digital Converter. The ADC0804 can operate, with 0v to 5v full
input range to give the 0-255 output.
For an input that is not full range, the ADC will have to be modified
with a Zero-Shift Adjust circuit configuration.
There are a variety of different
components that could have be used for the hardware. For instance the temperature sensor (LM35) and amplifier (KA358)
were one of many options that were available.
They were chosen based on their simplicity, availability.
Since the parallel port of the PC
can only receive 4 un-inverted bits at a time, a 74157 multiplexer was used to
send the byte of information one nibble at a time.
The following is the schematic of
the hardware used that was connected to the parallel port.
0.685V
1.39V
Fig 1.1 Data Acquisition Hardware
The voltage output for the 21ฐC (room temperature) was measure directly
form the LM35. The voltages for 5ฐC and 40ฐC were calculated with a formula that was
provided by the spec sheets.
The spec sheets state (Appendix A,
pg3) that there is a change of 10mV / ฐC. Resulting in the following
voltage outputs from the LM35, with respect to room temperature:
.455 volts for 5ฐC (calculated)
.715 volts for 21ฐC (measured)
.905 volts for 40ฐC (calculated)
The signal conditioning required an
offset adjustment in order to produced the desired binary values. The C++ coding interprets 0 binary value as
5ฐC and a 255 binary value as 40ฐC.
The LM35 produces a voltage range of .455v to .905v that is sent to the
KA358. The KA358 was setup as
differential operation amplifier, with a differential gain of 3. A voltage output of 1.39v to 2.76v will
result for temperatures in the range of 5ฐC to 40ฐC. This
output from the KA358 will be applied to an ADC.
Since the input range is not 0 to 5v
an offset adjustment was made to the ADC.
The ADC required extra circuitry in order to give a full 255-bit binary
digital output for an input that is not a 0 to 5 volt range. A Zero-Shift Adjust configuration was
used. The ADC will now convert 1.39
volts to 0 binary and 2.76 volts to 255 binary. This 8-bit binary value would then be sent to a
multiplexer.
The byte value received by the 74157
multiplexer is sent to the parallel port one nibble (4 bits) at a time. Depending on the status of the multiplexers
select line (high or low) will determine whether the upper or lower nibble is
sent. The assembly programming code
determines the status of the select line.
A 5-volt power supply circuit was
built to supply the hardware from a 120v AC to 12-volt DC adapter. The 12-volts were then rectified and
regulated to produce a stable positive 5-volts and ground output that supplied
the hardware.
A schematic of the power
supply:
Figure 1.2 5v power supply
Costing
and Reference
A list of the components and
materials used to build the hardware:
Qty Part
Number Description Price($)
Major
components
1 LM35 temperature
sensor 2.00
1 KA358 single source amplifier 1.50
1 ADC0804 analog to digital converter 4.00
1 SN74157 multiplexer 1.00
1 7400 NAND gate 1.00
1 MC7805 voltage regulator 2.50
Miscellaneous
components
5 1N4002 rectifiers 2.50
1 1N5226b
zener regulator 0.10
1 1N914 voltage offset 0.10
1 150pF RC filter 0.20
1 680uF filtering 1.00
1 10uF filtering 0.50
2 100K gain resistor 0.10
2 47K gain resistor 0.10
1 10K
ohm RC filter 0.05
2 2.7K
ohm current limiting 0.10
1 2.5K
ohm current limiting 0.05
2 10K
pot offset adjustors 6.00
1 1K
ohm current limiting 0.05
1 LED power indicator 0.75
1 waffle
board used to mount components 6.00
***** Total Price $29.60*****
Assembly portion of our program is used to communicate with the hardware connected at the parallel port. A hand shaking routine was established between program and hardware, making use of the status port (379h) and the control port (37Ah).
The first step is to send a sync pulse to keep the hardware and software in phase and to start off the entire analog to digital conversion process. The sync pulse, low-high-low, was sent to inverting pin 3 (write pin) of the ADC0804 though pin 1 of the control port (37Ah). Once the ADC0804 produces an 8-bit output, pin five of the ADC0804 (end of conversion) would go low. This end of conversion is monitored by pin 11 of port 379h. If pin 11 does not go low the program will be locked in a loop until it does. A high on pin 11 indicates that an analog to digital conversion has not been made.
The 8-bits are then sent to the 74157 (multiplexer). Pin 1 of the multiplexer, which is connected to pin 16 of the control port (37Ah), selects which nibble is to be sent to the port. A high on pin 1 (74157) selects the upper nibble and a low on pin 1 (74157) will select the lower nibble. The status port (379h) receives the upper and lower nibbles and the 8-bits are stored, through assembler code manipulation, in to the AL register and then moved to the variable data.
Flow Chart of
Assembly Code:
START
Output to 37ah
a sync pulse
Input from 379h
End of conversion
bit
Bit-7 = 0
AL w/ BL &
store in DATA
NO
Input from 379h
Lower nibble of
Byte
Shift lower nibble
Right 3 times and
Store in BL
Output from 37ah
A bit to the select
Pin of MUX
The C++
Coding
#include <stdio.h> // Standard Functions
#include <jni.h> // Java
Native Interface Functions
#include "SimpleSimpleServer.h"
JNIEXPORT
void JNICALL
Java_SimpleSimpleServer_serverSimple(JNIEnv *env, jobject obj)
{
unsigned char data = 0; //Return value
from A/D converter
jclass cls = env->GetObjectClass(obj);
jfieldID fid;
jdouble temp;
asm {
mov dx,37ah
//reset port //
mov
al,00h
out dx,al
mov al,01h
out dx,al
mov al,00h
out dx,al
here: mov dx,379h
//read & test pin #11
in al,dx
and al,80h //mask all but pin #7
jnz here
mov dx,379h
//read port
in al,dx
shr al,03h
//shift right
and al,0fh
mov bl,al
//remember nibble
mov dx,37ah //select = ONE
mov al,0Eh
out dx,al
mov dx,379h
//read port
in al,dx
shl al,01h
//shift right
and al,0f0h
//mask out lower 4 bits
add al,bl //remember upper nibble
mov data,al
//store result in buffer
}
fid =
env->GetStaticFieldID(cls, "temp", "D");
if (fid == 0){ return; }
temp
= data/5.6667 - 5.0;//converts the temperature data
env->SetStaticDoubleField(cls,
fid, temp);
}
These are the steps to integrate native code with the program written in Java.
With this process we implement a temperature-sensing program. The program has a Java class, called SimpleSimpleServer. SimpleSimpleserver.java must do two things: it declares a native method that gets temperature information and it implements the main method for the overall program. The implementation for the native method is provided in C++.
Note: We modify the signatures of C++ functions to work with the JNI. To use the correct signatures, it is best to begin by writing and compiling the Java code.
Method of writing native methods for Java programs is a multi-step process.
1. Write the Java program. Create a Java class that declares the native method; this class contains the declaration or signature for the native method. It also includes a main method, which calls the native method.
2. Compile the Java class that declares the native method and the main method.
3. Generate a header file for the native method using javah with the native interface flag -jni. Once generated the header file has the formal signature for our native method.
4. Write the implementation of the native method in the programming language of your choice (C++).
5. Compile the header and implementation (C++) files into a shared library file.
We compile the native language code into a shared
library. The runtime system later loads the shared library into the Java class
needing it. This maps the implementation of the native method to its declaration.
6. Run the Java program.
Note: Our program is exited using Ctrl-c.
The following figure illustrates these steps for the SimpleSimpleServer program:
Step 1: Write the Java Code ( program SimpleSimpleServer.java of this report).
Its method definition is: public native void serverSimple();
keyword
Step 2: Compile the Java Code
A:\>javac SimpleSimpleServer.java
This produces SimpleSimpleServer.class.
Step 3: Create the .h File
javah creates a JNI-style header file (a .h file) from the SimpleSimpleServer.class. The header file provides a function signature that implements the native method serverSimple.
A:\>javah -jni SimpleSimpleServer
Creating: SimpleSimpleServer.h
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class SimpleSimpleServer */ #ifndef _Included_SimpleSimpleServer #define _Included_SimpleSimpleServer #ifdef __cplusplus extern "C" { #endif /* Inaccessible static: temp */ #undef SimpleSimpleServer_defaultPort #define SimpleSimpleServer_defaultPort 80L /* * Class: SimpleSimpleServer * Method: serverSimple * Signature: ()V */ JNIEXPORT void JNICALL Java_SimpleSimpleServer_serverSimple (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
Step 4: Write the Native Method Implementation
We implemented the native method in a native language (C++) source file. The implementation is a regular function that's integrated with your Java class.
Our effort produced SimpleSimpleServer.cpp of this report.
Notice, the function used has the
same function signature as the one generated in SimpleSimpleServer.h:
JNIEXPORT void JNICALL
Java_SimpleSimpleServer_serverSimple(JNIEnv *, jobject)
Step 5: Create a Shared Library
We used Borland C++ 5.02 to compile the .h file and the .cpp file created in Steps 3 and 4 into a shared library. In Windows 95 terminology (&@humber), a shared library is called a dynamically load library (.dll).
The way we created the needed SimpleServe.dll file:
i. Copy SimpleSimpleServer.class and SimpleSimpleServer.h to C:\bc5\bin>, as there is not enough room in the A:\>.
ii. Go to menu ๏file๐then ๏new๐then๏project๐
In New Target Window edit:
Project Path and Name to C:\bc5\bin\SimpleServe.ide
and highlight Dynamic Library [.dll].
๏OK๐
Remember: This name decided
when SimpleSimpleServer.java
written:
Static {System.loadLibrary(SimpleServe);}
iii. Delete *.cpp & *.def of the project window, right click to add node to SimpleServe.dll ..addฎ A:SimpleSimpleServer.cpp.
iv. Go to menu ๏options๐then ๏project๐
Includeฎ (jni.h & other java related .h information)
๏OK๐
v. Go to menu ๏project๐
๏compile๐then ๏makeall๐to create the Dynamic Load Library.
vi. Copy SimpleServe.dll to the A: drive to run it from there.
Important Note: If you want to amend the resulting file, remember 15 files were created in the bin, that relate to this make; to amend, delete all 15 and start fresh. This may not be the best way but it worked for us.
Step 6: Run the Program
Use the Java interpreter, to run the program.
A:\>java SimpleSimpleServer
For more information on this approach we suggestion exploration of
http://java.sun.com/docs/books/tutorial/native1.1/stepbystep/
(The place to find a more in-depth narrative (), though the C& C compiler references are different as is the example.)
The descriptions in the above section are after the style of the material found at this reference.
Accessing the Java Member Variable
JNI provides a function that the native (C++) methods use to set the Java member variable, so we can get a class member variable.
SimpleSimpleServer.java contains a class with the class double member variable temp.
To set the Java member variable from our native (C++) language method,
ท Obtain the identifier of the member variable from its class, name, and type signature. The identifier for the class double member variable temp is:
fid = env->GetStaticFieldID(cls, temp,
D);
ท Set the member variable specified by the member identifier by giving temp a value, then use the member variable handling function:
env->SetStaticDoubleField(cls,
fid, temp);
All calls to JNI functions use the env pointer that is the first
argument of our native method. Also, env
is the first parameter of every JNI function, though this is transparent in C++
programs.
Note: member variable signatures follow the same encoding
scheme as method signatures.
member variable type
The member variable D refers to a double member variable, the same as the argument symbol in method signature.
For a summary of Java type signatures and their matching types, see:
http://java.sun.com/docs/books/tutorial/native1.1/summary/index.html
Also of interest in this case:
http://java.sun.com/docs/books/tutorial/native1.1/implementing/field.html
http://java.sun.com/docs/books/tutorial/native1.1/implementing/cpp.html
As for the actual temp value, it is the result of conversion of bit values, accessed by assembly language routine (described earlier) that represents a range of temperatures from -5ฐC through to 40ฐC. This is arbitrary and suits the current sensing range, but this conversion should be changed when other temperature ranges are to be observed.
Though, the conversion from data to temp,
produces a double value and the
display is formatted on the java side, to one decimal point. It should be
obvious that with the current set-up, only accuracy to ~1/5ฐ C is really possible.
Single decimal representation is there to clarify temperature movement.
NB: to generate the member signatures from class files, use the Java class
disassembler tool javap with
option -s:
A:\>javap -s -p SimpleSimpleServer
Compiled from SimpleSimpleServer.java
public class SimpleSimpleServer extends java.lang.Object {
static double
temp;
/* D
*/
public static
final int defaultPort;
/* I
*/
static {};
/* ()V
*/
public
SimpleSimpleServer();
/* ()V
*/
public static
void clientAction(java.io.InputStream,
java.io.OutputStream) throws java.io.IOException;
/*
(Ljava/io/InputStream;Ljava/io/OutputStream;)V */
public static
void main(java.lang.String[]);
/* ([Ljava/lang/String;)V */
private native
void serverSimple();
/* ()V
*/
}
The Main Method Implementation
As described earlier, the main method implementation is a server.
We make use of port 80, the default port to the internet. Port numbers are positive numbers with values up to 65535 (216-1). Operating systems commonly reserve ports numbers below 1024 (re: system services). This server is designed to be inclusive of concerns of larger systems then its intended PC home.
Establishing a simple server requires a call to a Socket constructor such as
ServerSocket
acceptor = new ServerSocket(port);
which binds the server to the port. The client connection is managed w/ the Socket object. ServerSocket listens indefinitely for clients (ie.a browser). The ServerSocket accept method:
Socket client = acceptor.accept();
which returns a Socket object establishing the connection.
To get the OutputStream and InputStream objects that enable server-client communications, we use a method call:
clientAction(client.getInputStream(),client.getOutputStream());
Referring to:
public static void clientAction(InputStream is, OutputStream os)
w/ clientAction method definition contained within curly braces{ the body of the method}, and variables within round braces (variables).
This in-turn is chained to a constructor:
OutputStreamWriter osw = new
OutputStreamWriter(os);
to instantiate or create an object which will compensate for limitations in java.net.* with flexibility from java.io.* to output the desired HTML et le information.
Note: information is only outputted, but infrastructure
exists for future development!
At this point the constructor SimpleSimpleServer(), is instantiated, so that the native method call can be make,
c.serverSimple();
The results of the native call SimpleSimpleServer.temp are tested against arbitrary conditions, which if circumstances merit result in the use of URLSender() constructors use to send a page to a concerned person, via an other site on the net.
Regardless, String s is produced, with HTML and formatted temp information.
This in turn is written and flushed to the net client browser.
As long as the client Socket exists the HTML META tag will request a fresh every second, re the HTML code.
//**
SimpleSimpleServer.java
import java.net.*;
import java.io.*;
import java.text.*;
public class SimpleSimpleServer {
static double temp;
static int n;
public final static int defaultPort =
80;
private native void serverSimple(); //declare
native method
public static void main(String[] args)
{ //main
program implementation
int port = defaultPort;
int n = 0;
try {port =
Integer.parseInt(args[0]);} catch (Exception
e) { } //keep
as integer, not string
if (port <= 1024 || port
>= 65536) port = defaultPort; //needed for bigger systems
System.out.println ("Running our
SimpleSimpleServer on port:"+port);
try {
ServerSocket acceptor = new ServerSocket(port);//register port(80) as available, await client
while (true) {
try {
Socket
client = acceptor.accept(); //method which returns socket object
System.out.println("Client connected"); //when established
clientAction(client.getInputStream(),client.getOutputStream());//method call
client.close();
}catch
(IOException e) {e.printStackTrace();}
}
}
catch (IOException e)
{e.printStackTrace();}
}//main()
static {System.loadLibrary("SimpleServe");} //naming the
shared library [dynamic load library (dll)]
public static void
clientAction(InputStream is, OutputStream os) //method
definition w/ variables
throws
IOException {
OutputStreamWriter osw = new
OutputStreamWriter(os); //constructor
// create and sent HTML page to client
SimpleSimpleServer c =
new SimpleSimpleServer(); //constructor
c.serverSimple(); //calling method
DecimalFormat oneDigit
= new DecimalFormat("0.0");
if
(SimpleSimpleServer.temp > 25 && n == 0){
URLSender my = new URLSender();//if temp high send "page"
n++;//send only one
page then reset needed!
}
String s = new
String("<HTML><HEAD><TITLE>\n Simple Simple Server \n
</TITLE><META HTTP-EQUIV=REFRESH CONTENT=1></HEAD><BODY>\n
<H1>Welcome to Simple Server!</H1>\n <H2> The
Temperature is "+oneDigit.format(SimpleSimpleServer.temp)+" degrees Celcius</H2>\n </BODY></HTML> ");
osw.write(s, 0,
s.length());
osw.flush();
}//clientAction()
} //class
}
class URLSender {
public
URLSender(){
try{
URL
uhoo = new
URL("http://pcstest.rogers.com:8080/cgi-bin/send_sm_rogers.new");
URLConnection connection =
uhoo.openConnection();
connection.setDoOutput(true);
PrintWriter out = new
PrintWriter(connection.getOutputStream());
out.print("msisdn" +
"=" + "4162335948" + "&");
out.print("area" +
"=" + "416" + "&");
out.print("num1" +
"=" + "233" + "&");
out.print("num2" +
"=" + "5948" + "&");
out.print("oldtext"
+ "=" + "temptest" + "&");
out.print("text" +
"=" + "temptest" + "&");
out.print("SIZEBOX"
+ "=" + "8" + "&");
out.print("SIZEBOXW"
+ "=" + "1" + "&");
out.print("sm_title"
+ "=" + "Rogers" + "%7C" + "Wireless" +
"&");
out.print("sm_header_ok" + "=" + "Thank" +
"You" + "&");
out.print("sm_header_fail" + "=" + "Sorry"
+ "&");
out.print("sm_ym" +
"=" + "Your" + "Message%3A" + "&");
out.print("sm_status_ok" + "=" +
"has+been+sent+to%3A&");
out.print("sm_status_fail=cannot+presently+be+sent+to%3A+&");
out.print("sm_logo=%2Fatt-logo.gif&");
out.print("sm_pcs_link=http%3A%2F%2Fwww.rogers.com%2Fenglish%2Fwireless%2Fsendpcs.html&");
out.print("sm_pcs_text=Send+a+PCS+message&");
out.print("sm_home_link=http%3A%2F%2Fwww.rogers.com&sm_home_text=home");
out.close();
BufferedReader in = new
BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
while((inputLine = in.readLine()) !=
null)
System.out.println(inputLine);
in.close();
} catch(Exception e)
{e.printStackTrace();}
}
}//class URLSender
To send out a Page, we have made use of the Rogers PCS page system, which is accessible through www.rogers.com, and is not to by confused with the alphanumeric pages accessible from the same site.
At www.rogers.com/engish/wireless/sendpcs.html , a look at the source code, reveals a <FORM> </FORM> structure. This structure has a rigid top down, format that is described in HTML 2.0 (RFC1866) 8.2 Form Submission.
This reference tells use how to translate the FORM into a one line expression.
http://pcstest.rogers.com:8080/cgi-bin/send_sm_rogers.new?msisdn=4162335948&area=416&num1=233&num2=5948&oldtext=temptest&text=temptest&SIZEBOX=8&SIZEBOXW=1&sm_title=Rogers+%7C+Wireless&sm_header_ok=Thank+You&sm_header_fail=Sorry&sm_ym=Your+Message%3A+&sm_status_ok=has+been+sent+to%3A&sm_status_fail=cannot+presently+be+sent+to%3A+&sm_logo=%2Fatt-logo.gif&sm_pcs_link=http%3A%2F%2Fwww.rogers.com%2Fenglish%2Fwireless%2Fsendpcs.html&sm_pcs_text=Send+a+PCS+message&sm_home_link=http%3A%2F%2Fwww.rogers.com&sm_home_text=home
Where ? is, read POST not GET. Awkward though this is, this information can be used in java to send the page temptest, to the PCS phone with the number (416) 233-5948, if it was a number with a account for this service with Rogers PCS phone service.
Note: a fast way to translate this is copy the completed HTML FORM to an other *.html file; change the POST to GET and double click on its icon to run it. The HTML will run, work out the code, than the result is presented in a browser window.
URLSender
was constructed using this approach. This class opens by trying to establish a URLconnection.
URL uhoo = new
URL("http://pcstest.rogers.com:8080/cgi- bin/send_sm_rogers.new");
URLConnection
connection = uhoo.openConnection();
Next, the connection is set up for output, by the setDoOutput method call.
connection.setDoOutput(true);
Then, getOutputStream is used to get the stream of data to the other server. PrintWriter is used to wrap the text stream so it can be sent.
PrintWriter out =
new
PrintWriter(connection.getOutputStream());
The data to be sent is in the out.print expressions.
The output stream is then closed.
BufferedReader is used to display to display return information on the screen monitoring the SimpleSimpleServer.
At present the main program will only send one page, then the program must be reset to find a condition to send another page. These are arbitrary conditions that reflect the fact that pages cost money, and we dont want to be a nuisance. Actual condition of operational circumstances may demand changes to this approach.
In response to our FORM submission Rogers sends a response, in the form of a HTLM page that confirms correct submission but only active accounts will get paged.
Conclusion
Some background knowledge of 8086 assembly language, C++ and Java was needed for the programming portion. We were exposed to assembly and C++ languages, but java programming required a steep learning curve. The hardware portion consisted of circuits that were developed from previously experimentation. A few new chips, LM35 and LM358, were dealt with for the first time. Interfacing the circuits to work in unison with the programming required numerous of trail runs and adjustments. One major concern was with the linearity response of the single source amplifier. An INA125p single source amp was originally used in the hardware design. But, the INA125p amp was not able to operate with the desired response. It was observed that INA125p would not operate linearly if the input voltages were not 1 volt above ground. For this reason the LM358 single source amplifier was chosen instead; it produced linear outputs for inputs less than 1v above ground.
A 5-volt regulating power supply that is supplied from a 120v AC to 12v DC jack, was included in the hardware design. Being able to supply the circuit from a 120v AC source made the circuit more practical and versatile. A 120v AC outlet is a more common source then a station with a ready-made 5volt supply.
Control of the ADC and multiplexing circuit control the hardware. The temperature sensor and amplifier were not controlled devices. This section did not operate in synchronous with the rest of the hardware. Theyre operation was to constantly gather and send data samples to the ADC. The ADC and multiplexer are the sections of hardware that do operate on demand. The combination of the two operated efficiently due to the assembly code.
Once again, the overall program is a server that serves a HTLM page, to the internet (port 80), with current temperature data which is made available by use of a Java Native Interface (JNI) with assembler /C++ (native) code. The program gets the temperature when a socket is established. The program gets a new temperature reading every second upon refresh by its HTLM page META tag (arbitrary) or just when refreshed, at the browser). Additionally, when the arbitrary temperature condition(s) is agreed, a page is sent. No temperature is measured if no socket is established.
This program should be thought of as a basis for development. It would good to develop the versatility to adjust temperature parameters over he internet; that involves security considerations. The reliability of Rogers PCS paging is at this writing is an unknown that needs resolving.
All in all the combination of a versatile temperature sensor worked by Java provided internet page, with regional paging alarm, has appeal.
We hope this report is instructive and encouraging to our peers. Java is clearly so versatile I can not be ignored.
http://java.sun.com/docs/books/tutorial/native1.1/stepbystep/index.html
start here and follow the prompts
a good resource:
Java how to program by Deitel & Deitel ISBN 0-13-012507-5
A advanced source:
Core Java 2 Volume II-Advanced Features
by CAY S. HORSTMANN ท GARY CORNELL
Sun Microsystems
ISBN
0-13-081934-4