Testing out the PPD42 Air Quality Sensor, with an MSP430 Launchpad and graphing the data with GNUplot.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

445 lines
16 KiB

// Generated by P Bennett: Monday, 4 October 1999 at: 05:24:32 pm
// Com Port Handler.
// I have released this code as a guide only.
// It will not run without the supporting classes.
// It was origanally written to communicate with a development prototype
// and runs under Slackware Linux Version 4 with Blackdown jdk1.1.7_v3
// Green Threads and rxtx version 3.4 with Java Comms API V2.0
// This thread is controlled by a thread that implements a queue
// and methods for controlling the queue and allocating the resources (modems)
// The modem used for development was a Siemens M20 Cellular modem.
// The remote equipment dumped its data upon connection and then hangs up.
// The protocol has changed somewhat now. (A Subset of HDLC)
// I have added extra comments for your benefit.
// It is free to use.
// Just a quick note. I have no formal training therefor the programming techniques
// may not be the best ones to use. However the technique I use has been developed
// through experience and it seems to work for me.
import java.util.*;
import java.io.*;
import gnu.io.*; //Comms Extensions
/** Class To Talk To A GSM Cellular Modem, Dial an SNU and retrieve the data.
* Uses Java Comm API 2.0
* @author P Bennett
* @version 1.0
* @see SNServerIO
* @see SNComThread
*/
public class SNComHandler extends java.lang.Thread implements
SerialPortEventListener {
private static SNComThread comThread; // A reference back to the parent.
private static SNLogger comLog; // Log handler
private static SNConfig serverConfig; // Server Configuration object
private String comName = "Nil"; // The com port name to use as in /dev/ttyS0
private boolean process = false; // Process a request
private String requestId = "Nil"; // Request ID
private String num = "Nil"; // The phone number to dial
private boolean running = true; // Make it go around
private CommPortIdentifier portId; // Port Identifier
private SerialPort serialPort = null; // Serial Port object
private OutputStream outputStream = null; // The streams
private InputStream inputStream = null;
private String errMessage = ""; // An error message
private boolean fatalErr = false; // Big problems call the emergency team :-(
private boolean waitForInput = true; // Wait for incoming data
/** Construct a new SNComHandler Object..
* For initialising the array of Com Handlers.
* @see SNComThread
*/
public SNComHandler() {
}
/** Construct a new SNComHandler Object.
* Created with the following parameters.
* @param cThread The parent thread.
* @param sLog The Logging object.
* @param sConfig The server config object.
* @param cName The Com Port name eg. /dev/ttyS0
* @see SNLogger
* @see SNConfig
*/
public SNComHandler(SNComThread cThread, SNLogger sLog, SNConfig
sConfig, String cName) throws NoSuchPortException {
this.comThread = cThread; // Parent thread
this.comLog = sLog; // Log object
this.serverConfig = sConfig; // Config object
this.comName = cName; // The com port name
portId =
(CommPortIdentifier)CommPortIdentifier.getPortIdentifier(this.comName);
// Set up the ID
this.comLog.log("Com Handler Initialised For " + comName); // Log start
}
/** Thread run method
* Call unit num, when requested and
* pass the recieved data back to
* the parent thread que.
*/
public void run() {
// comLog.debugInfo("Com Handler Run Method Started For " + comName);
int resetCount = 0; // Reset attempts
int resetCount2 = 0; // And again. There must be a better way
int resetCount3 = 0; // And again. of doing this!!!! They are all the same.
while (running) { // While we are doin it.
if (fatalErr) { // Big problems
comThread.queRequest(requestId, errMessage, "Error"); // Tell the parent
comLog.log(errMessage + " " + comName + " " + num); // Tell everyone
num = "Nil"; // Reset some variables
resetCount = 0; // The error resets process
resetCount2 = 0; // Round we go again.
resetCount3 = 0;
fatalErr = false;
}
if (!process) { // Nothing to do
try {
Thread.sleep(500); // Have a sleep
} catch (InterruptedException e) {}
continue; // Round we go again.
}
comLog.debugInfo("**********We Are Processing***********");
if (num.equals("Nil")) { // Can't dial Nil!
try { // Just a catch never tested
Thread.sleep(500); // Have a sleep
} catch (InterruptedException e) {} // Prolly does not work as intended
continue; // Round we go again.
}
comLog.debugInfo("**********Trying To Open Port***********");
if (!openPort()) { // Try to open port
closePort(); // Try to close it then
try {
Thread.sleep(500); // Have a sleep
} catch (InterruptedException e) {}
resetCount ++; // Up the counter
//***************** 3 goes in serverconfig ************************8
if (resetCount > 3) { // Check the counter
process = false; // We got problems
errMessage = "Error! Could Not Open Port";
fatalErr = true; // We got big problems
}
continue; // Round we go to sort it out
}
comLog.debugInfo("**********Trying To Reset Modem***********");
if (!reset()) { // We got the port now reset the modem
try {
Thread.sleep(500); // Have a sleep
} catch (InterruptedException e) {}
resetCount2 ++; // Up the counter
//***************** 3 goes in serverconfig ************************8
if (resetCount2 > 3) { // Check the counter
process = false; // We got problems
errMessage = "Error! Could Not Reset Modem";
fatalErr = true; // We got big problems
}
continue; // Round we go to sort it out
}
comLog.debugInfo("**********Trying To Dial***********");
if (!dial()) { // The modem reset OK now dial
comLog.debugInfo("**********" + errMessage + "***********");
try {
Thread.sleep(500); // Have a sleep
} catch (InterruptedException e) {}
resetCount3 ++; // Up the count
//***************** 3 goes in serverconfig ************************8
if (resetCount3 > 2) { // Check the count
process = false; // We got problems
errMessage = "Error! Could Not Dial";
fatalErr = true; // We got big problems
}
continue; // Round we go to sort it out
}
int numBytes = 0; // Number of bytes read from input
byte[] readBuffer = new byte[20]; // Tmp Read buffer of 20 bytes
String sReadBuff = ""; // Read Buffer
boolean dLoop = true; // Loop
while (dLoop) { // Wait for incoming data
try {
while (inputStream.available() > 0) { // While there is something to read
numBytes = inputStream.read(readBuffer); // Get the bytes
String tmpR = new String(readBuffer); // Set up a string
sReadBuff += tmpR.substring(0, numBytes); // Add to read buffer
}
} catch (IOException e) {
dLoop = false; // Problems
process = false; // This has never occured
}
if (sReadBuff.indexOf("NO CARRIER") != -1) { // Test incoming data
errMessage = ""; // Unit hangs up once it
dLoop = false; // dumps its data
} else if (sReadBuff.indexOf("ERROR") != -1) { // Check for error
errMessage = "Error! Recieved Data Not Clean " + num + " " + comName;
dLoop = false;
} else if (sReadBuff.length() > 5000) { // Check for receive runnaway
errMessage = "";
dLoop = false;
}
}
if (errMessage.equals("")) { // No error occured
comThread.queRequest(requestId, sReadBuff, "Ready"); // Tell the parent the result
comLog.log("Data Recieved " + " " + requestId + " " + num); // Log it
System.out.println("*********" + sReadBuff + "*********"); // Raw Debug code
} else {
if (!fatalErr) { // Error
comThread.queRequest(requestId, errMessage, "Error"); // Tell parent
comLog.log(errMessage + " " + comName + " " + num); // Log
System.out.println("*********" + errMessage + "*********"); // Raw debug
}
}
closePort(); // Close the port
resetCount = 0; // Reset the variables ready for next request
resetCount2 = 0;
resetCount3 = 0;
num = "Nil";
process = false;
}
}
/** Open Com Port
* @return true if succesfull
*/
private boolean openPort() {
if (serialPort == null) { // Set up serial port object if need be
comLog.debugInfo("**********Open Port Routine***********");
try {
serialPort = (SerialPort) portId.open("SimpleReadApp", 2000); // Open serial port
comLog.debugInfo("**********Port Open***********");
} catch (PortInUseException e) {
return false; // Hmm its in use
}
if (inputStream == null) { // Set up the input stream if need be
try {
inputStream = serialPort.getInputStream(); // Get the stream
} catch (IOException e) {
return false;
}
}
if (outputStream == null) { // Set up the output stream if need be
try {
outputStream = serialPort.getOutputStream(); // Get the stream
} catch (IOException e) {
return false;
}
}
try {
serialPort.addEventListener(this); // Add the event listener
} catch (TooManyListenersException e) {
return false;
}
serialPort.notifyOnDataAvailable(true); // Set the port to notify on incoming data
//********* Maybe this goes in serverconfig maybe on a per port basis
// Set the port parameters
try {
serialPort.setSerialPortParams(19200, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {
return false;
}
}
return true; // Everything went ok
}
/** Close Com Port. */
private void closePort() {
if (serialPort != null) { // Check that the serial port is not null
serialPort.notifyOnDataAvailable(false); // Close down notification
serialPort.removeEventListener(); // Remove the event listener
if (inputStream != null) { // Check for null
try {
inputStream.close(); // Close it
inputStream = null; // Clean up
}
catch (IOException e) {}
}
if (outputStream != null) { // Check for null
try {
outputStream.close(); // Close it
outputStream = null; // Clean up
}
catch (IOException e) {}
}
serialPort.close(); // Close the serial port
serialPort = null; // Clean up
}
}
/** Reset The Modem
* @return true if succesfull.
*/
private boolean reset() {
try {
outputStream.write(new String("atz").getBytes()); // Send the modem atz
outputStream.write((byte)0x0D); // And the other stuff
outputStream.write((byte)0x0A); // <CR> <LF>
} catch (IOException e) {
return false;
}
int waitingCount = 0; // Heres another counter
waitForInput = true; // We are waiting
while (waitForInput) { // Yes we are
try {
Thread.sleep(100); // We have a little rest
} catch (InterruptedException e) {}
waitingCount ++; // We count
//***************** 20 goes in serverconfig ************************
if (waitingCount > 20) { // We have counted to much
return false; // Could not reset
}
}
int numBytes = 0; // Set up number of bytes read
byte[] readBuffer = new byte[20]; // And a buffer
String sReadBuff = ""; // And another buffer
try {
while (inputStream.available() > 0) {
numBytes = inputStream.read(readBuffer); // Read from the port
String tmpR = new String(readBuffer);
sReadBuff += tmpR.substring(0, numBytes);
}
} catch (IOException e) {
return false;
}
//********************Maybe for serverconfig
if (sReadBuff.indexOf("OK") != -1) { // Test for OK response from modem
try {
Thread.sleep(1000); // We have another sleep to allow things
} catch (InterruptedException e) {} // to settle
return true;
}
return false; // We did not reset OK
}
/** Dial number requested
* @return true if connected
*/
private boolean dial() {
try {
comLog.debugInfo("**********" + num + "***********");
outputStream.write(new String("atd").getBytes()); // Send atd
outputStream.write(num.getBytes()); // And the number
outputStream.write((byte)0x0D); // And the other stuff
outputStream.write((byte)0x0A);
} catch (IOException e) {
errMessage = "Error! Could Not Write To Port ";
comLog.debugInfo("**********Error Writing***********");
return false; // Bad could not write
}
int waitingCount = 0; // We are counting again
waitForInput = true; // Waiting
while (waitForInput) {
try {
Thread.sleep(100); // Have a sleep
} catch (InterruptedException e) {}
waitingCount ++; // Counting
//**************** For serverconfig ************************
if (waitingCount > 200) { // Counted to much
errMessage = "Error! Timed Out Waiting For Response";
return false; // Timed out
}
}
int numBytes = 0; // Set up for reading
byte[] readBuffer = new byte[20]; // Youve seen it before
String sReadBuff = ""; // The comments are getting thinner
boolean dLoop = true; // No need to repeat
while (dLoop) {
try {
while (inputStream.available() > 0) {
numBytes = inputStream.read(readBuffer);
String tmpR = new String(readBuffer);
sReadBuff += tmpR.substring(0, numBytes); // We read it
}
if (sReadBuff.indexOf("NO CARRIER") != -1) { // Out of area
errMessage = "Error! No Carrier";
return false;
} else if (sReadBuff.indexOf("BUSY") != -1) { // Busy
errMessage = "Error! Busy"; // Who is ringing our units
return false; // Maybe it is dialing out
} else if (sReadBuff.indexOf("NO DIAL TONE") != -1) { // Bad no signal
errMessage = "Error! No Dial Tone"; // Were has the ariel gone
return false;
} else if (sReadBuff.indexOf("OK") != -1) { // Hmm voice call no good
errMessage = "Error! Voice Call";
return false;
} else if (sReadBuff.indexOf("CONNECT") != -1) { // Ah this is what we want
return true; // Return true
}
} catch (IOException e) {
errMessage = "Error! Could Not Read From Com Port";
return false; // Bad but never happened yet
}
}
errMessage = "Error! Invalid Data " + sReadBuff;
return false; // Something has gone wrong
}
/** Serial Event Routine
* Set waitForInput to false when data ready
*/
public void serialEvent(SerialPortEvent event) {
switch(event.getEventType()) {
case SerialPortEvent.BI:
case SerialPortEvent.OE:
case SerialPortEvent.FE:
case SerialPortEvent.PE:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.RI:
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
break;
case SerialPortEvent.DATA_AVAILABLE:
waitForInput = false; // We got incoming
break; // Thats it for serial events
}
}
/** Process Request To Call SNU.
* Request that a call be made and the data
* returned to the controlling thread.
* @see SNComThread
*/
public void processRequest(String req, String num) {
requestId = req; // Set ID
this.num = num; // Set the phone number
process = true; // Make it go
}
/** Is Processing Call
* @return true if thread is busy
* @see SNComThread
*/
public boolean isProcessing() {
return process; // Are you busy
}
/** Is Processing This Q Id.
* @param qID The ID to test for
* @return true if the thread is processing qID
* @see SNComThread
*/
public boolean isProcessing(String qID) {
return requestId.equals(qID); // Are you busy doing this job
}
}
/* the following was added so the code will compile. Its not proper */
class SNLogger
{
public void debugInfo(java.lang.String it)
{
}
public void log(java.lang.String it)
{
}
}
class SNComThread
{
public void queRequest(java.lang.String a, java.lang.String b, java.lang.String c)
{
}
}
class SNConfig
{
}