[[TOC(heading=Table of Contents, Docs/Prog/Manual/DeviceSupport/*)]] [[PageOutline]] = 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. ||Response||Input 1||Input 2||Input 3||Input 4|| ||0||Off||Off||Off||Off|| ||1||On||Off||Off||Off|| ||2||Off||On||Off||Off|| ||3||On||On||Off||Off|| ||4||Off||Off||On||Off|| ||5||On||Off||On||Off|| ||6||Off||On||On||Off|| ||7||On||On||On||Off|| ||8||Off||Off||Off||On|| ||9||On||Off||Off||On|| ||A||Off||On||Off||On|| ||B||On||On||Off||On|| ||C||Off||Off||On||On|| ||D||On||Off||On||On|| ||E||Off||On||On||On|| ||F||On||On||On||On|| ''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. {{{ #!Lineno #!c extern uint32 g_nRepIOIntv; extern struct set_dio_struct mnbd_set_dio; extern struct mnbd_dio_status_struct mnbd_dio_status; // Read I/O status every 100 ms g_nRepIOIntv = 100; MnBdRequest(MNBD_DEV, MNBD_REQ_REP_IO_STATUS, NO_WAIT_ACK); sleep(1); while(1) { if(CheckIORcv(MNBD_DEV)) { if((mnbd_dio_status.inputs & 1) != 0) { // Input 1 active -- Set output 1 and break out of loop mnbd_set_dio.output = 0x01; mnbd_set_dio.mask = 0x0F; MnBdRequest(MNBD_DEV, MNBD_REQ_SET_IO_STATUS, NO_WAIT_ACK); break; } } } // Stop repeating I/O status g_nRepIOIntv = 0; MnBdRequest(MNBD_DEV, MNBD_REQ_REP_IO_STATUS, NO_WAIT_ACK); }}} 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. {{{ #!Lineno #!c // required include file from lib825 #include "DioEvent.h" int main() { // indicator startup (open mainboard, etc) // dio example DioEvent event; int scale = 1; int board = 0; int pin = 0x01; float fTarget = 250.00; // set up the event int myEvent = event.addEvent(scale,EVENT_GROSS,EVENT_LESS,fTarget,board,pin); // optionally add a conditional statement to it event.addCondition(myEvent,scale,EVENT_GROSS,EVENT_GREATER,0,EVENT_AND); // start the individual event event.startEvent(myEvent); // OR you can start all events event.startAll(); // indicator shutdown (close mainboard, etc) return 0; } }}} 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 === {{{ #!Lineno #!c #include #include #include "kypdbeep.h" #include "lcd.h" #include "mnbdcomm.h" extern uint16 g_dio_count; extern int g_keycnt; extern uint8 g_keybuf[KEYBUF_SIZE]; extern struct set_dio_struct mnbd_set_dio; int main() { char szCnt[41]; struct timespec delaytm; delaytm.tv_sec = 0; delaytm.tv_nsec = 1000000; // 1 ms InitLCD(); ClearLCD(); OpenBeeper(); PrintLCD("DIO Counter Test\r"); PrintLCD("Press '1' - '4' to toggle outputs"); int input; // Note - all four input pins of mainboard may be used for counting, options card may use only one of inputs 1 - 7 for // counting and input 8 may always be used for counting. OpenMnBd(MNBD_DEV); struct { int init_cnt; int prescaler; DIOSetReg up_or_down; DIOSetReg low_or_high; } test[4] = { // Experiment with different options to observe different counter behavior // Count Prescaler Count Up or down Count on low to high, or high to low { 0, 1, dioSetCountUp, dioSetCountLowToHigh }, { 10, 1, dioSetCountDown, dioSetCountLowToHigh }, { 0, 1, dioSetCountUp, dioSetCountHighToLow }, { 100, 2, dioSetCountDown, dioSetCountLowToHigh } }; for(input = 1; input <= 4; input++) { if(SetDIOCounter(MNBD_DEV, input, dioSetCount, test[input-1].init_cnt, WAIT_ACK) != MNBD_REQ_ACK_RCVD) { PrintLCD("Cannot set count\r"); } if(SetDIOCounter(MNBD_DEV, input, dioSetPrescaler, test[input-1].prescaler, WAIT_ACK) != MNBD_REQ_ACK_RCVD) { PrintLCD("Cannot set prescaler\r"); } if(SetDIOCounter(MNBD_DEV, input, test[input-1].up_or_down, 0, WAIT_ACK) != MNBD_REQ_ACK_RCVD) { PrintLCD("Cannot set count up\r"); } if(SetDIOCounter(MNBD_DEV, input, test[input-1].low_or_high, 0, WAIT_ACK) != MNBD_REQ_ACK_RCVD) { PrintLCD("Cannot set count low to high\r"); } if(SetDIOCounter(MNBD_DEV, input, dioEnableCounter, 0, WAIT_ACK) != MNBD_REQ_ACK_RCVD) { PrintLCD("Cannot enable counter\r"); } } input = 1; mnbd_set_dio.output = 0; int req_cnt = 3000; int n; GetDIOCounter(MNBD_DEV, input, dioGetCount, NO_WAIT_ACK); while(1) { ReadKeypad(); if(g_keycnt > 0) { g_keycnt = 0; if(g_keybuf[0] == ESC) break; // Keypad keys "1" through "4" will toggle state of output which is looped back to input // so that we can observe operation of counter if(g_keybuf[0] >= '1' && g_keybuf[0] <= '4') { mnbd_set_dio.mask = 0x000F; n = g_keybuf[0] - '1'; if(mnbd_set_dio.output & (1 << n)) { mnbd_set_dio.output &= ~(1 << n); LocateLCD(n * FONT_WIDTH * 10, FONT_HEIGHT * 3); PrintLCD(" "); } else { mnbd_set_dio.output |= (1 << n); LocateLCD(n * FONT_WIDTH * 10, FONT_HEIGHT * 3); PrintLCD("on"); } MnBdRequest(MNBD_DEV, MNBD_REQ_SET_IO_STATUS, WAIT_ACK); nanosleep(&delaytm, NULL); input = n + 1; req_cnt = 1; } } req_cnt--; if(req_cnt == 0) { GetDIOCounter(MNBD_DEV, input, dioGetCount, NO_WAIT_ACK); req_cnt = 3000; } nanosleep(&delaytm, NULL); if(CheckDIOCountRcv(MNBD_DEV)) { sprintf(szCnt, "%6d", g_dio_count); LocateLCD((input - 1) * FONT_WIDTH * 10, FONT_HEIGHT * 2); PrintLCD(szCnt); if(input == 4) input = 1; else input++; req_cnt = 5; } } // Done - disable the counters for(input = 1; input <= 4; input++) { if(SetDIOCounter(MNBD_DEV, input, dioDisableCounter, 0, WAIT_ACK) != MNBD_REQ_ACK_RCVD) { PrintLCD("Cannot disable counter\r"); } } CloseMnBd(MNBD_DEV); ClearLCD(); return 0; } }}}