Wednesday, April 17, 2024

Java Serial Class that works with Numato Labs USB I/O device.

This product is interesting because it is relatively cheap and does not require special software or drivers.  If you have an old PC laying around, you can install Linux Mint on it for free and use this instead of spending the cash on a Raspberry Pi.  I did just that to solve a minor problem at our manufacturing facility.  We have a warning light that goes off in our clean room which indicates that the particle count is out of specification.  The problem was, the employees did not have any sort of timer telling them how long it has been active.  After wiring this in parallel to the warning light, I created a Java application that pops up a warning label and a timer.  After 3 minutes they must immediately shut down.  An alternative to Java would be Python and the tkinter library, which I initially tried.  I find it much easier to make nicer graphics in Java.  By the time you buy a Raspberry PI 5 and all the required accessories, you might as well find yourself a bare bones mini PC.





package alarm_monitor;

import com.fazecast.jSerialComm.SerialPort;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

public final class mySerialPort {

    private SerialPort port;

    public mySerialPort() {
        connect();
    }
    
    public boolean connect() {
        SerialPort[] ports = SerialPort.getCommPorts();

        if (ports.length > 0) {
            for (SerialPort port1 : ports) {
                if (port1.getDescriptivePortName().equals("Numato Lab 8 Channel USB GPIO Module")) {
                    port = port1;
                }
            }
            if (port != null) {
                port.setBaudRate(19200);
                port.setNumDataBits(8);
                port.setNumStopBits(SerialPort.ONE_STOP_BIT);
                port.setParity(SerialPort.NO_PARITY);
                port.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);
                port.setComPortTimeouts(SerialPort.TIMEOUT_NONBLOCKING, 250, 250);
                return true;
            }
        }
        return false;
    }

    public void close() {
        if (port != null) {
            port.closePort();
        }
    }

    public String getPortInfo() {
        StringBuilder sb = new StringBuilder();
        for (SerialPort myPorts : SerialPort.getCommPorts()) {
            sb.append(port.getSystemPortPath()).append(": ").append(myPorts.getDescriptivePortName()).append("\n");
        }
        return sb.toString();
    }

    public boolean isOpen() {
        if (port != null) {
            return port.isOpen();
        } else {
            return false;
        }
    }

    public int getAlarmStatus() {

        String dataToWrite;

        try {
            OutputStream outputStream;
            int[] intData;
            try (InputStream inputStream = port.getInputStream()) {
                outputStream = port.getOutputStream();
                port.openPort();
                dataToWrite = "gpio set 0\r";
                outputStream.write(dataToWrite.getBytes());
                outputStream.flush();
                Thread.sleep(200);
                byte[] inputBuffer = new byte[inputStream.available()];
                inputStream.read(inputBuffer);
                dataToWrite = "gpio read 1\r";
                outputStream.write(dataToWrite.getBytes());
                outputStream.flush();
                Thread.sleep(200);
                inputBuffer = new byte[inputStream.available()];
                int bytesRead = inputStream.read(inputBuffer);
                intData = new int[bytesRead];
                for (int i = 0; i < bytesRead; i++) {
                    intData[i] = inputBuffer[i] & 0xFF;
                }
            }
            outputStream.close();
            port.closePort();

            return intData[13] - 48;

        } catch (Exception ex) {
            Logger.getLogger(mySerialPort.class.getName()).log(Level.SEVERE, null, ex);
            return -1;
        }
    }





Wednesday, March 6, 2024

HMI and controls to test consumable copy machine part

This machine tests several key quality parameters for a consumable part for copy machines.  This particular part consists of 8 very small diameter wires, only a few thousands of an inch diameter, that are placed on a plastic frame with a Fanuc robot.  There are two groups of four wires, like a very tiny guitar.  The spacing and tension on the wires are critical and this test machine verifies the key parameters are in tolerance.  It also saves production data to an SQL file.  Here is a link to the GUI I created and another link to the consumable Part being testing in the machine.  The GUI made it easier to troubleshoot the process, since it provided a graphical representation of the frequency response of each wire and a clear pass/fail diagram for the operator.


Friday, February 9, 2024

Small Control Cabinet with Productivity 1000 PLC

  I created this control cabinet to interface a 100 ton Trane chiller and four pumps to a pure steam generator and collect water and nitrogen usage data.  Our Niagara BMS polls this processor for data using ModbusTCP.





Thursday, December 15, 2022

Python program to communicate with a wireless BACnet thermostat.



CLICK HERE TO VIEW PYTHON PDF

The thermostat is a BAST-221C-BW2 from Contemporary Controls and the cost is very reasonable at $160.  This version is wireless which is ideal for home use.  The thermostat does not come with a weekly schedule function since it was made primarily for industrial applications where this would be handled by a building management system.  

The program reads the following parameters from the thermostat one time each minute: currentTemperature, activeTemperatureSetpoint, coolingTemperatureSetpoint, heatingTemperatureSetpoint, coolingHeatingStatus, relayStatus1, relayStatus3, relayStatus7, fanStatus.  It then stores the data in a SQLITE3 database which is open source.  I used SQLITE STUDIO to query the data.

The program is running on a Dell laptop running Linux Mint.



Tuesday, November 22, 2022

OG&E Energy Savings Rebate $194,839.27

I earned a $194k rebate from OG&E for my former employer in Yukon, OK.  The project involved the specification and installation of a correctly sized air compressor and dryer.  At the award ceremony I was told that it was the second largest rebate ever awarded in Oklahoma.




Thursday, August 4, 2022

Historical trends via Canary Labs and Axiom trending.  The extruder is running great since the retrofit.  Shown in the chart are two independent sources for extruder speed.  Percent current is also displayed which is proportional to extruder pressure.  The characteristic sawtooth wave of the two gravimetric feeders is also shown.  The key metric is melt flow index but the value can only be obtained at twenty minute intervals due to limitations in the lab process.