Abfragen der ADC-Kanäle

In dem folgenden Beispiel wird gezeigt, wie die Multithreading-Fähigkeiten von JControl verwendet werden können, um in einer Applikation kontinuierlich die Messwerte der ADC-Kanäle aufzunehmen, ohne den normalen Programmablauf dadurch zu beeinträchtigen. So kann im Vordergrund beispielsweise eine grafische Benutzerschnittstelle angezeigt werden, während im Hintergrund automatisch auf Änderungen von Messwerten reagiert wird.

Unsere Applikation soll zunächst herausfinden, wie viele ADC-Kanäle auf dem System verfügbar sind und dann entsprechend viele Threads starten, die die Messwerte kontinuierlich einlesen. Der folgende Quelltext zeigt, wie diese Aufgabe mit JControl realisiert werden kann.

1    import jcontrol.io.ADC;
2    import jcontrol.io.Display;
3    import jcontrol.lang.ThreadExt;
4    import jcontrol.system.Management;
5    
6    /**
7     * This example shows how to read out ADC values on JControl.
8     * Furthermore, the usage of multiple threads in one application
9     * is demonstrated.
10    
11     * <p>(C) DOMOLOGIC Home Automation GmbH 2003</p>
12     */
13    public class ADCExample {
14      /** array to store ADCReader instances in */
15      ADCReader adcreaders[];
16     
17     
18      /**
19       * Inner class <code>ADCReader</code> realizes a thread
20       * that continuously reads and stores ADC values.
21       */
22      class ADCReader extends Thread {
23        /** adc channel */   
24        int channel;
25        /** last read value */
26        int value = 0;   
27        /** thread instance */
28        Thread instance = null;
29       
30        /**
31         * Constructs an <code>ADCReader</code> thread.
32         * @param channel the ADC input channel to read values from
33         */
34        public ADCReader(int channel) {
35          instance = this;
36          this.channel = channel;
37          this.start();
38        }
39       
40        /**
41         * This method is invoked when the thread execution starts.
42         * @see java.lang.Runnable#run()
43         */
44        public void run() {
45          while (instance == this) {
46            // read current adc value
47            value = ADC.getValue(channel);
48           
49            // sleep for 100 millis
50            try {
51              ThreadExt.sleep(100);
52            } catch (InterruptedException e) {}
53          }
54        }
55       
56        /**
57         * Stop thread execution.
58         */
59        public void quit() {
60          instance = null;
61        }
62       
63        /**
64         * Retrieve current adc value
65         */
66        public int getValue() {
67          return value;
68        }
69      }
70    
71    
72      /**
73       * Constructs an <code>ADCExample</code> instance.
74       * We start as many <code>ADCReader</code> threads as
75       * adc input channels exist.
76       */
77      public ADCExample() {
78        String s = Management.getProperty("io.adcchannels");
79        int numchannels = Integer.parseInt(s);
80       
81        adcreaders = new ADCReader[numchannels];
82       
83        // create ADCReader threads and store instances into an array
84        for (int i=0; i<numchannels; i++)
85          adcreaders[i] = new ADCReader(i);
86         
87        // draw adc status continuously on lcd   
88        drawStatus();
89      }
90     
91     
92      /**
93       * Draw ADC values (read by ADCReader threads) on lcd
94       */
95      void drawStatus() {
96        Display lcd = new Display();
97       
98        while (true) {
99          lcd.clearDisplay();
100         
101          // show adc values on lcd   
102          for (int i=0; i<adcreaders.length; i++) {
103            lcd.drawString("ADC channel ".concat(
104                            String.valueOf(i)).concat(" value: ").concat(
105                            String.valueOf(adcreaders[i].getValue())),
106                           0, 8*i);
107          }
108         
109          // sleep for 500 millis
110          try {
111            ThreadExt.sleep(500);
112          } catch (InterruptedException e) {}
113        }
114      }
115    
116      /**
117       * Main method. Program execution starts here.
118       */
119      public static void main(String[] args) {
120        new ADCExample();
121      }
122    }
Listing 1: ADCExample.java

Die Hauptklasse ADCExample enthält eine innere Klasse ADCReader, welche die Eigenschaften eines Thread-Objekts erfüllt. Wenn der Thread durch einen Aufruf der Methode start gestartet wird, (hier im Konstruktor public ADCReader(int channel)), folgt automatisch ein Aufruf der Methode run(). Diese liest in einer Endlosschleife alle 100ms den aktuellen Wert des im Konstruktor spezifizierten ADC-Kanals ein. Dazu wird die getValue-Methode aus der ADC-Klasse verwendet.

Die Aufgabe der Hauptklasse ADCExample ist einfach: Es müssen lediglich genau so viele ADCReader-Instanzen erzeugt werden wie ADC-Kanäle im System verfügbar sind. Die Anzahl letzterer kann durch einen Aufruf der Methode Management.getProperty("io.adcchannels") auf jedem JControl-System erfragt werden. Wurden die ADCReader-Instanzen erzeugt, läuft die kontinuierliche Messwerterfassung ohne weiteres Zutun der Hauptklasse automatisch im Hintergrund.