Immutable

This sample requires that the MODBUS Server is running.

This sample is meant to show you how to gain access to the MODBUS scratch memory space. You can see in the MODBUS manual that the MODBUS addressing assigns a “scratch” address space starting at WORD 256.

Since WORDs are 2 bytes we know that the starting address is going to be 512. We can gain access to the “scratch” area by opening the Modbus00 immutable block. The Modbus00 immutable block does not exist until the MODBUS server has been started on the unit at least once in its lifetime. You can use the nv command to discover whether the Modbus00 block exists or not.

If the Modbus00 block does not exist then execute the MODBUS Server. Once the MODBUS Server has been executed the Modbus00 will exist.

The immutable example shown in the Immutable Class example uses an array of long values. We will use a byte array in this example.

package modbussample;  
  
import com.integpg.system.ArrayUtils;  
import com.integpg.system.Immutable;  
  
  
  
public class ModbusSample {  
  
    public static void main(String[] args) throws InterruptedException {  
        // open the Modbus00 immutable block  
        System.out.println("Open the MODBUS Store");  
        byte[] modbusStore = Immutable.getByteArray("Modbus00");  
  
        // if the block does not exist then alert the user and exit.  it is not our responsibility to create it  
        if (modbusStore == null) {  
            System.out.println("MODBUS store has not been created.  Please run the MODBUS Server application.");  
            System.exit(0);  
        }  
  
  
        // the modbus store must exist.  loop so that external changes by a client are seen by our application  
        while (true) {  
            // get and print the first 4 WORDs in our scratch area  
            short[] value = new short[]{  
                ArrayUtils.getShort(modbusStore, 512),  
                ArrayUtils.getShort(modbusStore, 514),  
                ArrayUtils.getShort(modbusStore, 516),  
                ArrayUtils.getShort(modbusStore, 518)  
            };  
            System.out.println("WORDs @0256: " + value[0] + ", " + value[1] + ", " + value[2] + ", " + value[3]);  
  
  
            // get and print the first 8 bytes that represent the first 4 WORDs in our scratch area  
            byte[] b = new byte[8];  
            ArrayUtils.arraycopy(modbusStore, 512, b, 0, b.length);  
            System.out.println("bytes @0512: " + hexDump(b, 0, b.length));  
  
  
            // sleep a little before checking again  
            Thread.sleep(1000);  
        }  
    }  
  
  
  
    public static String hexDump(byte[] bytes, int offset, int length) {  
        StringBuffer sb = new StringBuffer();  
        StringBuffer chars = new StringBuffer();  
  
        int i;  
        for (i = offset; i  
                < length; i++) { if (i % 16 == 0) { if (chars.length() > 0) {  
                    sb.append("  ");  
                    sb.append(chars.toString());  
                    chars  
                            = new StringBuffer();  
                    sb.append("\r\n");  
                }  
  
            } else if (i % 16 == 8) {  
                chars.append(" ");  
                sb.append("  ");  
            }  
  
            if (bytes[i] >= 32) {  
                chars.append((char) bytes[i]);  
            } else {  
                chars.append('.');  
            }  
  
            int p = sb.length();  
            sb.append(Integer.toHexString((bytes[i] & 0xff) / 16));  
            sb.append(Integer.toHexString((bytes[i] & 0xff) % 16));  
            sb.append(" ");  
        }  
  
        int mod = i % 16;  
        if (mod != 0) {  
            if (mod <= 8) { sb.append(" "); } for (i = 16 - (mod); i > 0; i--) {  
                sb.append("   ");  
            }  
  
            sb.append("  ");  
            sb.append(chars.toString());  
        }  
  
        return sb.toString();  
    }  
  
}  

Here is some sample output from our application. We used a PC MODBUS client to adjust the values of the registers in the MODBUS scratch address space. You can see the values changing during the execution of our application.

This sample shows you how to use the Immutable class. The immutable class represents persistent storage that can be accessed at the low level as an array of primitive types. This example shows the use of an array of longs. The long values in this application are date values that represent when the application was started.

package immutablesample;  
  
import com.integpg.system.Immutable;  
import java.util.Date;  
  
  
  
public class ImmutableSample {  
  
    public static void main(String[] args) {  
  
        // get an array of long values that represent the last 5 boot times  
        long[] lastFiveBootTimes = Immutable.getLongArray("BootTimes");  
  
        // if the array does not already exist then create an array of 5 long values  
        if (lastFiveBootTimes == null) lastFiveBootTimes = Immutable.createLongArray("BootTimes", 5);  
  
  
        // shift the previous 4 boot times  
        for (int i = 4; i > 0; i--) {  
            lastFiveBootTimes[i] = lastFiveBootTimes[i - 1];  
        }  
  
  
        // assign the most recent boot time  
        lastFiveBootTimes[0] = System.currentTimeMillis();  
  
  
        // loop through our last five boot times and print them in a readable format  
        for (int i = 0; i < 5; i++) {  
            long bootTime = lastFiveBootTimes[i];  
  
            if (bootTime > 0) {  
                System.out.println(new Date(bootTime));  
            }  
        }  
    }  
  
}