§1.  Overview

This demo tries to be a simple example of what type of applications can be created with NutDAC. The tutorial goes step by step through different features so that you can get at least a general idea. It is not, by any means, a complete description of all the features.

The demo is based on the adc_dio example provided with NutDAC, which explains how to use the microcontroller's ADCs (in case of Ethenut2) and GPIO pins as binary inputs and outputs. It does not contain any special control loop in either ethernut and PC sides, it is though to be as a simple application in which the user is the controller. You will be able to do (in real time):

  • Remotely control and monitor the system from a comfortable GUI
    • See the history of the ADC readings in a chart
    • Control the binary output pins with buttons
    • See the status of the binary inputs with a simple display
    • Change some calibration parameters
    • Store the data in your computer
    • See the logs from the system and send commands from a command line interface
  • Locally control the system through a serial command line interface

The channels used are:

Channel Direction Port/Pin
1-8 analog input ADC inputs(Ethernut2)/ None(Ethernut3)1
9 binary output pin 41 of the Ethernut's hardware expansion port
10 binary output pin 42 of the Ethernut's hardware expansion port
11 binary input pin 45 of the Ethernut's hardware expansion port
12 binary input pin 46 of the Ethernut's hardware expansion port

(1) because the Ethernut3 does not have ADCs, channels 1 to 8 will show random numbers, just to be able to see some kind of noisy measurement for demonstration purposes

For examples of more complex applications, check the control programs developed for the 8kW and 16kW fuel cell based power sources with 100 and 188 I/O channels respectively.

§1.1  Prerequisites

  • Either an Ethernut2 or Ethernut3 connected to the network
  • A computer with java installed and connected to the network
  • A serial cable to connect the Ethernut to the computer (or two, if you can connect both serial ports)

§1.2  Quick steps

In case you just want to have a quick glance, here are quick steps to get the app started:

  • Connect your Ethernut2 or 3 to the network. It will use the IP, be sure that your computer can route packets to that address (i.e. set an ip alias)
  • Program the Ethernut. Use
  • Execute the GUI AdcDio-applet.jar
    java -jar AdcDio-applet.jar
  • Play!

You can always refer to the different sections of this demo for details.

§2.  Preparation

§2.1  Connections to the Hardware Expansion Port

It is not necessary to connect anything to the pins of the Ethernut to run this demo. Having said so, some further comments:

  • If the pins corresponding to the ADCs (Analog Input Port) of the Ethernut 2 are left unconnected you will see floating voltages in the charts, which can be nice for a demo. But of course you can connect some channels to VCC or ground, or whatever other signal you might want to measure between 0 and 5 volts.
  • We recommend to connect LEDs (with series resistor) to the binary outputs, so you can see them turning on and off.
  • The binary inputs can be connected to VCC or ground to see them ON(channel value 1) or OFF (channel value 0). If left unconnected the voltage will be floating and you will see them changing the state randomly.

§2.2  Ethernut Connectivity

  • Connect the Ethernut to the network
  • Connect a computer to the the serial port of the Ethernut (you can use a USB to serial adaptor). If possible (not required), connect both serial ports. A control terminal will be shown in the first one and the system logs in the second. You will need a special cable adaptor connected to the Ethernut to get the signals of the second serial port (see the Ethernut RS-232 Primer).
  • Open a serial terminal emulator (i.e. Putty), or two, if you could connect both serial ports, and connect to the Ethernut (115200bps, 8 data bits, 1 stop bit, no parity, no flow ctrl.). The terminal uses VT100 commands, so if possible enable that in your terminal emulator. Also you might have to add an implicit CR in every LF.

§2.3  Program the Ethernut

Upload the following file to your Ethernut using your favourite method:

When the Ethernut boots you should see the something like this in your terminal emulators windows

(Note:from now on and for simplicity we will not show pictures of the terminals, only the text)
The left one shows the the first serial port with the control terminal, and the right one the second one (in case you connected it) with the system logs. From the logs you can see, among other things, what services have been started and when. For example, the network was started in the millisecond 21, and the Slogger server in the millisecond 1053.

Now let's check the network connectivity. Configure the computer with the IP and mask (you can create an IP alias). The Ethernut will send UDP packets to this IP. Then try to ping the Ethernut from your coputer

jose@Aut-019:~$ ping
PING ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=64 time=1.14 ms
64 bytes from icmp_seq=2 ttl=64 time=1.13 ms
64 bytes from icmp_seq=3 ttl=64 time=1.11 ms

--- ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 1.117/1.130/1.141/0.009 ms

§3.  GUI

The example can be executed as a java application or as an applet. Moreover, you can embed the applet in a web page that can be downloaded from the web server of the Ethernut.

  • To run the example as a java application download AdcDio-applet.jar to any directory of your computer and run the application
    java -jar AdcDio-applet.jar
  • To run the example as a java applet download also index.html and place it in the same directory than AdcDio-applet.jar. Then open index.html with a java enabled browser.
  • To download the GUI from the Ethernut's web server simply upload the files to its root directory as follows:

- The Ethernut2 uses Michael Fisher's Xflash file system for the serial flash memory. Download the xflash.bin containing the GUI and upload it using your favourite tftp client. In windows we use

tftp -i PUT xflash.bin
and in linux

atftp -p -l xflash.bin --trace

- The Ethernut3 uses the SD card to store the files. Get a card reader for your computer and copy AdcDio-applet.jar and index.html to the root directory. Then insert the card in the Ethernut3 and reboot it.

Open your favourite (java enabled) browser and go to the address

In either case the GUI shows a tabbed panel with the following tabs: System Control, Calibration, Data recorder and Term/Logs

§3.1  System Control

Press Connect and you should see something like this

The System Control tab contains the widgets to control the system and the displays.

The chart visualizes the values returned by the ADCs. The slider in its left controls the amount of points displayed in the chart. The numerical values of the channels can be seen in the right side. You can control many aspects of the visualization with the pop up menu that appears right clicking in the chart. You can also right click in the labels in the bottom of the chart to select individual options for each channel trace.

We also have two buttons to control the status of the output pins (pins 41 and 42) and two indicators of the status of the inputs pins (pins 45 and 46).

The status of the channels is updated every second by the dms server running in the microcontroller, which triggers new channel transactions with a configurable period. You can configure this period from the control terminal, as you soon will see. You can configure also different modes of updating every channel, and even choose to use UDP or TCP sockets for the channel updates. Check the Data Monitor Server and Events modules of the NutDAC_Micro API documentation for details.

§3.2  Calibration

The Calibration tab contains tools to set the calibration parameters, as explained in the NutDAC_Micro API documentation (ChAL module -> NdChannel -> Channel calibration). We have seen that the chart in the System Control tab displays the values returned by the ADC (in fact the values returned by the channel driver), that is, values between 0 and 1023. We can use the calibration to display for example volts instead, so values between 0 to 5. We thus require a linear transformation that can be uniquely defined by two points: (0,0) and (1023,5). Those will be the calibration parameters that we will use.

Go to the Calibration tab. It should look like this

It has the first channel selected. The Range Panel shows the calibration parameters in use and the default ones saved in non volatile memory (An asterisk means that it is not saved). Using the sliders we would first set the minimum point, and then press the button Set min. But note that the minimum is already set to (0,0), so it is not necessary. We then set the maximum also with the sliders: select 1023 with the Raw and 5 with the Converted sliders respectively (to extend the range of the slider, right click and enter the new range). You can also type the values in the text field under the sliders (and press intro). Then press Set max.

The Refresh button triggers a new channel transaction and shows in the raw slider the status of the channel as returned by the channel driver. This can be useful when doing manual calibrations in the field.

In order to save the new calibration parameters in the non volatile memory, press the Save button. You should see something like this

Now do the same for all the remaining ADC channels (2 to 8), one at a time (they can all be also set from the command line with a single command using channel groups, as we will see later). Go to the System Control tab again and you will see that the values displayed are between 0 and 5. The chart will auto adjust the vertical axis to the maximum range of all the points displayed, so you will have to wait a bit until older points are gone to see a smaller scale in the Y axis.

The mathematical transformation between the raw anc "converted" values that we have used in this example is a simple linear one that uses the calibration parameters stored in the non volatile memory of the microcontroller. NutDAC_GUI provides a mechanism to define and use arbitrary complex transformations. See the converters package of in the NutDAC_GUI API

§3.3  Recording Data

The 'Data Recorder' tab contains a panel for recording the data in the computer.

You can choose between 2 modes of recording:

Raw mode: all the channel data coming from the Ethernut will be recorded. The format is
where the y value represents the converted value as seen in the calibration section.

Scanned mode: the status of the channels are recorded periodically with a selectable interval. Note that new transactions are not triggered, which means that the recorded channel status is that one stored by NutDAC at that moment, which corresponds to the latest valid transaction. The scanned mode stores the data as follows: the data is organized in columns. The first element of each column is the name, and the rest are values. The first column contains the timestamps and the rest of the columns the y values of the channels (as stored in the GUI, that is, after the transformation that we saw in the previous section).

Data can be also recorded in the SD card of the Ethernut3. See the SD reporter documentation.

§3.4  Terminal and Logs

The 'Term/Logs' tab contains two panels:

The left panel contains a terminal from where the system can be controlled with written commands. You can also see all the commands that the GUI have sent since its start.

The right panel shows the system logs starting from the moment of the connection. System logs have up to 6 levels of importance, and by defining the level to use, lower important logs will not be shown. By default NutDAC logs many different types of events, but the importance can be configured as per module basis. Also user application can easily add its own logs. Check the System Logger documentation.

Logs are shown in the GUI with different colours, one colour for each importance level.

Logs also can be stored in the SD card of the Ethernut3. Actually they can be sent through any FILE stream, check the System Logger documentation).

§4.  The Command Line Interface

There are two command line interfaces available: one through the serial port and another through a socket. The syntax of the commands is exactly the same, whereas the exact output is not. The one through a socket is designed for use by a program from a remote computer (in this case the GUI), and it does not show a prompt. Although it is not purely a telnet server (it does not handle negotiations), you can use a telnet client to connect to it. It accepts only one connection at a time, so don't connect to it when the GUI is connected. The one through the serial port is designed for use with humans, and is the one that we show here.

§4.1  Predefined commands

The control terminal accepts several predefined commands. For details, see the NutDAC commands of the Command Line Interface module in the NutDAC_Micro API documentation. To view all the registered commands press Tab twice.

nut     trace   ch      ds      gr
sl      ev

If you want to get a (very)short reminder of what each command does, simply type the command with no arguments . For example

ch error: no arguments. Usage:
NAME    ch - channel operation

        ch [id] [cmd] [args]

        Performs an operation on the selected channel/group

        [id]  target channel/group
        [cmd] the command to execute on the given channel/group
                * Transfer commands
                tm  - transfer memory                   - no args
                tml - transfer memory live              - no args
                tn  - transfer new                      - value
                tnl - transfer new live                 - optional
                * Calibration commands
                cg  - calibration get                   - no args
                cs  - calibration set                   - Xm,Ym,XM,YM
                csv - calibration save                  - no args
                csi - calibration set interactive       - (interactive)
                cdg - calibration default get           - no args
                cds - calibration default set           - no args
                cr  - calibration reset to def values   - no args
                * Monitoring commands
                mg  - monitoring get                    - no args
                ms  - monitoring set                    - mode (0 < 4)
                msi - monitoring set interactive        - (interactive)
                mdg - monitoring get def values         - no args
                mds - monitoring set def values         - mode (0 < 4)
                mr  - monitoring reset to def values    - no args
                * Info commands
                ig  - info get                          - no args
                igl - info get live                     - no args
                igs - info synchronization              - no args
                * Events notification settings commands
                ng - Events notification mask get       - no args
                ns - Events notification mask set       - mask
                * Emulation commands
                es   - emulation set                    - 1/0
                esi  - emulation set interactive        - (interactive)
                eg   - emulation get                    - no args
                evs  - emulation value set              - X
                evsi - emulation value set interactive  - (interactive)
                evg  - emulation value get              - no args
        [args] the arguments required for each command

In the rest of this demo we will use only some of the commands.

§4.2  Channel operations

If you want to get information about certain channel use the ch x ig, where x is the channel id. For example:

[nd]$ch 1 ig
ID       Name    Type    Xm      Ym      XM      YM      Value   TimeStamp       Monitoring      EventsMsk
1       ADC_1   1       0           0   1023     1023       0              0    2:Periodic New          6

We can see that channel 1 is associated to the first channel of the internal ADC of the microcontroller. To get a new measurement (trigger a new transaction)

[nd]$ch 1 tn
1         255        5147683

The first column of the response shows the id of the channel selected, the second the measurement (255 in this case) and the third the timestamp of the measurement (millisecond 5147683 after bootup). If you want to retrieve the last valid transaction on a channel (kept in memory) use the transfer form memory option

[nd]$ch 1 tm
1         255        5147683

which shows the the exact same output than before, because there has not been any newer transaction (transactions can be triggered from many threads!). It would be nice if we could get measurements periodically from the command line interface, simply to see fresh measurements. Use the live options

[nd]$ch 1 tnl
Starting live dump
ID       Name    Value   TimeStamp
1       ADC_1     240        5585824

You should see how the value and timestamp are changing about once per second. To stop press any key.

§4.3  Groups of channels

It would still be nice if we could get measurements of all the ADCs with a single command. For that we use the groups of channels. For this demo we have created the following groups

[nd]$gr ls

So one group with all the channels, another with the ADCs, another with the digital inputs and the last one with the digital outputs. Should you want more groups, you can create them also from the command line (see the gr command). So lets trigger a periodic transaction on all the ADCs. Simply use the name of the group instead of a channel id (channel number)

[nd]$ch adcs tnl
Starting live dump
ID       Name    Value   TimeStamp
1       ADC_1     575         300489
2       ADC_2     496         300491
3       ADC_3     432         300493
4       ADC_4     385         300496
5       ADC_5     768         300498
6       ADC_6     768         300500
7       ADC_7     481         300501
8       ADC_8     768         300504

again, press any key to stop it.

§4.4  Increasing the sampling rate

The data server (or data monitor server, dms) takes care of triggering periodic transactions on the channels (as configured per channel by the user). Check the documentation of the Data Monitor Server module for details. Here we will show how to increase the frequency with which the data server triggers channel transactions. For that we will use the ds command. First let's see what is the actual period

[nd]$ds lg

so we can see that the data server is triggering one transaction (on each configured channel) every 1000 milliseconds. Let's trigger transactions every 100 ms

[nd]$ds ls 100

If you see now the System Control tab of the GUI, you will see that the ADC measurements appear much faster. Now you might wonder: what is the maximum frequency? Well, that depends on the controller that you are using and the load of your system. What it is certain is that, even if the data server tries to use the sampling period set by the user, NutOS is not preemptive, and thus the execution time cannot be guaranteed. Sure you can try to set the latency to 0, but in order to avoid blockage of the system, the limit has been set implicitly by forcing a minimum of 1ms sleep between loops, to let other threads (even with lower priority) take over the processor. This does NOT mean that the maximum sampling frequency allowed by NutDAC is 1kHz, as transactions can be triggered from any other thread (dms is executed in its own thread). This limit is only applicable to the dms server, and the ultimate limit of the highest sampling frequency is defined by the hardware used.