wiki:Docs/Prog/Manual/DeviceSupport/DIO

DIO

The 825 main board is equipped with four digital input and four digital output ports. DIO option cards may be used for additional I/O options. Option cards contain eight ports which may be used as a combination of inputs and outputs.

Digital I/O

The console command prompt may be used for simple DIO testing.

echo “L000000020000000F” > /dev/mnbd

This sets the state of the mainboard digital outputs. The “L” is the command, the following 8 characters or four hexadecimal bytes represent the state desired. The final 8 characters or four hexadecimal bytes represent a mask of which outputs are to be affected. In this example “F” is used as the mask to set the state of all four on-board outputs.

# echo “I” > /dev/mnbd

This requests the status of the mainboard digital I/O.

# cat < /dev/mnbd

response:

# IA000000000

The last 8 character of the response are hexadecimal digits. Of these the first 4 digits are the state of the digital inputs. The final 4 digits are the state of the outputs. If the input 1 only is active the response is:

# IA000010000

If inputs one and two are active the response is:

# IA000030000

If inputs one, two, three, and four are active the response is:

# IA0000F0000

Only a single hexadecimal digit is needed to represent the state of the four mainboard inputs.

ResponseInput 1Input 2Input 3Input 4
0OffOffOffOff
1OnOffOffOff
2OffOnOffOff
3OnOnOffOff
4OffOffOnOff
5OnOffOnOff
6OffOnOnOff
7OnOnOnOff
8OffOffOffOn
9OnOffOffOn
AOffOnOffOn
BOnOnOffOn
COffOffOnOn
DOnOffOnOn
EOffOnOnOn
FOnOnOnOn

For additional structure formats refer to MainboardProtocol?

The lib825 library provides functions to facilitate applications performing digital I/O tasks.

To perform these tests with DIO option cards replace /dev/mnbd with /dev/wt1 (for the first DIO option card), /dev/wt2 (for the second installed DIO option card), etc...

The following example shows program code to read and set DIO ports.

Line 
1extern uint32 g_nRepIOIntv;
2
3extern struct set_dio_struct mnbd_set_dio;
4extern struct mnbd_dio_status_struct mnbd_dio_status;
5
6// Read I/O status every 100 ms
7g_nRepIOIntv = 100;
8MnBdRequest(MNBD_DEV, MNBD_REQ_REP_IO_STATUS, NO_WAIT_ACK);
9
10sleep(1);
11
12while(1)
13{
14   if(CheckIORcv(MNBD_DEV))
15   {
16      if((mnbd_dio_status.inputs & 1) != 0)
17      {
18           // Input 1 active -- Set output 1 and break out of loop
19
20           mnbd_set_dio.output = 0x01;
21           mnbd_set_dio.mask = 0x0F;
22           MnBdRequest(MNBD_DEV, MNBD_REQ_SET_IO_STATUS, NO_WAIT_ACK);
23           break;
24      }
25   }
26}
27
28// Stop repeating I/O status
29g_nRepIOIntv = 0;
30MnBdRequest(MNBD_DEV, MNBD_REQ_REP_IO_STATUS, NO_WAIT_ACK);
31

To use this example with a DIO option card replace MNBD_DEV with the number of the installed DIO option card such "1" for the first DIO option card, or "2" for the second installed DIO option card.

If MNBD_REQ_REP_IO_STATUS is used for repeat status on multiple DIO cards or the mainboard and another DIO card at the same time it will be impossible to mnbd_dio_status structure and determine which card is providing the input. However, an array of structures is provided dio_status[x] where x = 0 mainboard, x = 1 first DIO card, x = 2 second DIO card, etc...

For digital I/O event operations refer to the DioEvent? class.

DIO Events

About

This document will guide the programmer through the process of creating and using a simple DIO Event using the DioEvent? class provided in the standard library (lib825). DIO Events are processed by the mainboard in order to allow a level of redundancy. Should the OPI board kernel crash the mainboard will continue to provide relay functionality and will disable events when their thresholds are reached.

The Code

To use a DIO event follow the example code below.

Line 
1
2// required include file from lib825
3#include "DioEvent.h"
4
5int main() {
6  // indicator startup (open mainboard, etc)
7
8  // dio example
9  DioEvent event;
10
11  int scale = 1;
12  int board = 0;
13  int pin = 0x01;
14  float fTarget = 250.00;
15
16  // set up the event
17  int myEvent = event.addEvent(scale,EVENT_GROSS,EVENT_LESS,fTarget,board,pin);
18
19  // optionally add a conditional statement to it
20  event.addCondition(myEvent,scale,EVENT_GROSS,EVENT_GREATER,0,EVENT_AND);
21
22  // start the individual event
23  event.startEvent(myEvent);
24
25  // OR you can start all events
26  event.startAll();
27
28  // indicator shutdown (close mainboard, etc)
29  return 0;
30}

The above code would create an event that would enable board 0 (mainboard) pin 0 when the gross weight of scale 1 is less than 250.00 and greater than 0.00.

DIO Counting

Description

Mainboard software 1.15 is required for counting feature. Kernel 2009-10-07 or later is required. All four inputs of the mainboard may be used for counting. The DIO cards allow any one of inputs 1 - 7 to be used for counting. Input 8 may also be used for counting. This allows for up to two inputs per DIO card to be used for counting.

Example

Line 
1
2#include <stdio.h>
3#include <stdlib.h>
4
5#include "kypdbeep.h"
6#include "lcd.h"
7#include "mnbdcomm.h"
8
9extern uint16 g_dio_count;
10
11extern int g_keycnt;
12
13extern uint8 g_keybuf[KEYBUF_SIZE];
14extern struct set_dio_struct mnbd_set_dio;
15
16int main() {
17
18        char szCnt[41];
19
20        struct timespec delaytm;
21        delaytm.tv_sec = 0;
22        delaytm.tv_nsec = 1000000;  // 1 ms
23
24        InitLCD();
25        ClearLCD();
26
27        OpenBeeper();
28
29        PrintLCD("DIO Counter Test\r");
30        PrintLCD("Press '1' - '4' to toggle outputs");
31
32        int input;
33
34        // Note - all four input pins of mainboard may be used for counting, options card may use only one of inputs 1 - 7 for
35        // counting and input 8 may always be used for counting.
36
37        OpenMnBd(MNBD_DEV);
38
39        struct {
40                int init_cnt;
41                int prescaler;
42                DIOSetReg up_or_down;
43                DIOSetReg low_or_high;
44        } test[4] = {
45                        // Experiment with different options to observe different counter behavior
46                        //  Count  Prescaler    Count Up or down    Count on low to high, or high to low
47                        {               0,      1,              dioSetCountUp,          dioSetCountLowToHigh },
48                        {          10,          1,              dioSetCountDown,        dioSetCountLowToHigh },
49                        {               0,              1,              dioSetCountUp,          dioSetCountHighToLow },
50                        {         100,          2,              dioSetCountDown,        dioSetCountLowToHigh }
51        };
52
53        for(input = 1; input <= 4; input++)
54        {
55                if(SetDIOCounter(MNBD_DEV, input, dioSetCount, test[input-1].init_cnt, WAIT_ACK) != MNBD_REQ_ACK_RCVD)
56                {
57                        PrintLCD("Cannot set count\r");
58                }
59
60                if(SetDIOCounter(MNBD_DEV, input, dioSetPrescaler, test[input-1].prescaler, WAIT_ACK) != MNBD_REQ_ACK_RCVD)
61                {
62                        PrintLCD("Cannot set prescaler\r");
63                }
64
65                if(SetDIOCounter(MNBD_DEV, input, test[input-1].up_or_down, 0, WAIT_ACK) != MNBD_REQ_ACK_RCVD)
66                {
67                        PrintLCD("Cannot set count up\r");
68                }
69
70                if(SetDIOCounter(MNBD_DEV, input, test[input-1].low_or_high, 0, WAIT_ACK) != MNBD_REQ_ACK_RCVD)
71                {
72                        PrintLCD("Cannot set count low to high\r");
73                }
74
75                if(SetDIOCounter(MNBD_DEV, input, dioEnableCounter, 0, WAIT_ACK) != MNBD_REQ_ACK_RCVD)
76                {
77                        PrintLCD("Cannot enable counter\r");
78                }
79        }
80
81        input = 1;
82
83        mnbd_set_dio.output = 0;
84
85        int req_cnt = 3000;
86        int n;
87        GetDIOCounter(MNBD_DEV, input, dioGetCount, NO_WAIT_ACK);
88
89        while(1)
90        {
91                ReadKeypad();
92                if(g_keycnt > 0)
93                {
94                        g_keycnt = 0;
95                        if(g_keybuf[0] == ESC)
96                                break;
97                        // Keypad keys "1" through "4" will toggle state of output which is looped back to input
98                        // so that we can observe operation of counter
99                        if(g_keybuf[0] >= '1' && g_keybuf[0] <= '4')
100                        {
101                                mnbd_set_dio.mask = 0x000F;
102                                n = g_keybuf[0] - '1';
103                                if(mnbd_set_dio.output & (1 << n))
104                                {
105                                        mnbd_set_dio.output &= ~(1 << n);
106                                        LocateLCD(n * FONT_WIDTH * 10, FONT_HEIGHT * 3);
107                                        PrintLCD("  ");
108                                }
109                                else
110                                {
111                                        mnbd_set_dio.output |= (1 << n);
112                                        LocateLCD(n * FONT_WIDTH * 10, FONT_HEIGHT * 3);
113                                        PrintLCD("on");
114                                }
115
116                                MnBdRequest(MNBD_DEV, MNBD_REQ_SET_IO_STATUS, WAIT_ACK);
117                                nanosleep(&delaytm, NULL);
118
119                                input = n + 1;
120                                req_cnt = 1;
121                        }
122                }
123
124                req_cnt--;
125                if(req_cnt == 0)
126                {
127                        GetDIOCounter(MNBD_DEV, input, dioGetCount, NO_WAIT_ACK);
128                        req_cnt = 3000;
129                }
130
131                nanosleep(&delaytm, NULL);
132
133                if(CheckDIOCountRcv(MNBD_DEV))
134                {
135                        sprintf(szCnt, "%6d", g_dio_count);
136                        LocateLCD((input - 1) * FONT_WIDTH * 10, FONT_HEIGHT * 2);
137                        PrintLCD(szCnt);
138
139                        if(input == 4)
140                                input = 1;
141                        else
142                                input++;
143
144                        req_cnt = 5;
145                }
146        }
147
148        // Done - disable the counters
149        for(input = 1; input <= 4; input++)
150        {
151                if(SetDIOCounter(MNBD_DEV, input, dioDisableCounter, 0, WAIT_ACK) != MNBD_REQ_ACK_RCVD)
152                {
153                        PrintLCD("Cannot disable counter\r");
154                }
155        }
156
157        CloseMnBd(MNBD_DEV);
158
159        ClearLCD();
160
161        return 0;
162}
163
164
Last modified 8 years ago Last modified on Nov 30, 2009, 4:03:43 PM