基于asyn的arduino驱动程序开发

设备之间连接如下图: 

 

Arduino的程序文本的串口通信协议设计以及在Arduino上的应用_arduino串口通信协议-优快云博客中说明:

1、DO0~DO2对应设置Arduino的数字量输出-管脚[8,12,13]。
2、DI0~DI2对应读取Arduino的数字量输入-管脚[2,4,7]。
3、AO0~AO2对应设置Arduino的模拟量输出-管脚[3,5,6]。
4、AI0~AI2对应设置Arduino的模拟量输入-管脚[A0,A1,A2]。

arduino上连线如下:

  • DO0 <-> DI0
  • DO1 <-> DI1
  • DO2 <-> DI2
  • AI0 <-> GND
  • AI1 <-> 5V
  • AI2 <-> 3.3V

IOC应用程序开发如下:

1、建立IOC程序框架:

root@lubancat:/usr/local/EPICS/program# mkdir asynArduino
root@lubancat:/usr/local/EPICS/program# cd asynArduino/ 
root@lubancat:/usr/local/EPICS/program/asynArduino# makeBaseApp.pl -t ioc asynArduino
root@lubancat:/usr/local/EPICS/program/asynArduino# makeBaseApp.pl -i -t ioc asynArduino
Using target architecture linux-aarch64 (only one available)
The following applications are available:
    asynArduino
What application should the IOC(s) boot?
The default uses the IOC's name, even if not listed above.
Application name?
root@lubancat:/usr/local/EPICS/program/asynArduino#

2、编辑configure/RELEASE文件,添加EPICS_BASE和ASYN环境变量所指向的支持目录: 

# RELEASE - Location of external support modules
#
...

EPICS_BASE = /usr/local/EPICS/base

SUPPORT=/usr/local/EPICS/synApps/support
ASYN=$(SUPPORT)/asyn

...
-include $(TOP)/configure/RELEASE.local

3、进入 asynArduinoApp/src/源文件目录:

root@lubancat:/usr/local/EPICS/program/asynArduino# cd asynArduinoApp/src/

编写arduino.h和arduino.cpp源文件,源代码如下: 

/*
        arduino.h
*/
#ifndef arduino_H
#define arduino_H
#include <epicsEvent.h>
#include <epicsTypes.h>

#define DEFAULT_TIMEOUT         2.0
#define POLL_TIME                       0.5
#define MAX_CHANNELS            3
#define NUM_ANALOG_IN       3
#define NUM_ANALOG_OUT      3
#define NUM_IO_BITS         3
#define MAX_SIGNALS         NUM_IO_BITS
#define INPUTBUFFERLEN      100

#define arduinoDOString         "ARDUINO_DO_STRING"
#define arduinoDIString         "ARDUINO_DI_STRING"
#define arduinoAOString         "ARDUINO_AO_STRING"
#define arduinoAIString         "ARDUINO_AI_STRING"

static const char *driverName = "asynArduinoDriver";

class asynArduinoController : public asynPortDriver{
public:
        asynArduinoController(const char *portName, const char *serverPort ,int channels, int numParams,
                                        int interfaceMask, int interruptMask);

        virtual ~asynArduinoController(){};

        /* overriding methods from asynPortDriver */
        virtual asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value);
        virtual asynStatus writeUInt32Digital(asynUser *pasynUser,
                                                                                epicsUInt32 value, epicsUInt32 mask);
        virtual void report(FILE *fp, int details);

        /* new method*/
        virtual asynStatus sendReceive(const char*, char*, unsigned int );
    virtual asynStatus sendOnly(const char *outputBuff);
        virtual bool resetConnection(){return false;};
    void        arduinoPoller();
    virtual asynStatus startPoller(double pollPeriod);
    static void callPoller(void*);
    static void callShutdown(void * ptr){((asynArduinoController*)ptr)->shutdown();};
    void shutdown();

        int shuttingDown_;

protected:
        #define FIRST_ARDUINO_PARAM arduinoDO_;
        int arduinoDO_;
        int arduinoDI_;
        int arduinoAO_;
        int arduinoAI_;
        #define LAST_ARDUINO_PARAM arduinoAI_;
        double pollPeriod_;
        epicsMutex *baseMutex;
        asynUser *pasynUserController_;
        char inputBuffer[INPUTBUFFERLEN];
    char pollInputBuffer[INPUTBUFFERLEN];

        asynStatus sendReceiveLock(const char* outbuffer, char* inbuffer, unsigned int );
    asynStatus sendOnlyLock(const char * outbuffer);
};

#define NUM_ARDUINO_DRIVER_PARAMS (&LAST_ARDUINO_PARAM - &FIRST_ARDUINO_PARAM + 1)
#endif
/* arduino.cpp */
#include <stdlib.h>
#include <string.h>

#include <epicsThread.h>
#include <iocsh.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <epicsExit.h>
#include <asynPortDriver.h>
#include <asynOctetSyncIO.h>
#include "arduino.h"
#include <epicsExport.h>
#include <shareLib.h>

#ifndef VERSION_INT
#  define VERSION_INT(V,R,M,P) ( ((V)<<24) | ((R)<<16) | ((M)<<8) | (P))
#endif

#define ARDUINO_ASYN_VERSION_INT VERSION_INT(ASYN_VERSION,ASYN_REVISION,ASYN_MODIFICATION,0)

#define VERSION_INT_4_32 VERSION_INT(4,32,0,0)

#define DEBUG

asynArduinoController::asynArduinoController(const char *portName, const char * serverPort, int channels, int numParams,
                                         int interfaceMask, int interruptMask)

  : asynPortDriver(portName, channels,
#if ARDUINO_ASYN_VERSION_INT < VERSION_INT_4_32
                   NUM_ARDUINO_DRIVER_PARAMS+channels,
#endif
        interfaceMask |  asynFloat64Mask | asynUInt32DigitalMask | asynDrvUserMask,
        interruptMask |  asynFloat64Mask |  asynUInt32DigitalMask,
        ASYN_MULTIDEVICE | ASYN_CANBLOCK , 1 , 0 , 0),
        shuttingDown_(0), pollPeriod_(POLL_TIME)
{
        static const char *functionName = "asynArduinoController";
        asynStatus status;

        /* Create the base set of motor parameters */
        createParam(arduinoDOString,     asynParamUInt32Digital,        &arduinoDO_);
        createParam(arduinoDIString,     asynParamUInt32Digital,        &arduinoDI_);
        createParam(arduinoAOString,     asynParamFloat64,                      &arduinoAO_);
        createParam(arduinoAIString,     asynParamFloat64,                      &arduinoAI_);

        baseMutex = new epicsMutex;

        status = pasynOctetSyncIO->connect(serverPort, 0, &pasynUserController_, NULL);
        if (status) {
        asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
        "%s:%s:%s: cannot connect to virtual motor controller\n",
        driverName, functionName, portName);
        }

        epicsAtExit(asynArduinoController::callShutdown, this);
}

asynStatus asynArduinoController::writeFloat64(asynUser *pasynUser, epicsFloat64 value)
{
        int addr;
        int function = pasynUser->reason;
        asynStatus status= asynSuccess;
        static const char *functionName = "writeIFloat64";
        int i;
        double volt;
        char temp[20];

        this->getAddress(pasynUser, &addr);
        setDoubleParam(addr, function, value);

        if (function == arduinoAO_){
                sprintf(pollInputBuffer, "VOLTS:SET:");
                for (i =  NUM_ANALOG_OUT -1; i >=0 ; i--){
                    getDoubleParam(i, function, &volt);
                        sprintf(temp, "%.2f:", volt);
                    strcat(pollInputBuffer, temp);
                }
                int len = strlen(pollInputBuffer);
                pollInputBuffer[len-1] = '\0';

        //printf("send:%s\n", pollInputBuffer);
                status = sendOnlyLock(pollInputBuffer);
        }

        callParamCallbacks(addr);
        if (status == asynSuccess) {
        asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
             "%s:%s, port %s, wrote %.2f to address %d\n",
             driverName, functionName, this->portName, value, addr);
        } else {
        asynPrint(pasynUser, ASYN_TRACE_ERROR,
             "%s:%s, port %s, ERROR writing %.2f to address %d, status=%d\n",
             driverName, functionName, this->portName, value, addr, status);
  }

  return status;
}

asynStatus asynArduinoController::writeUInt32Digital(asynUser *pasynUser, epicsUInt32 value, epicsUInt32 mask)
{
        int function = pasynUser->reason;
        asynStatus status = asynSuccess;
        int i;
        char temp[100];
        static const char *functionName = "writeUInt32Digital";

        setUIntDigitalParam(function, value, mask);
        //printf("function=%d, arduinoDO_=%d\n", function, arduinoDO_);
        //printf("value=0x%x, mask=0x%x\n", value, mask);

        if (function == arduinoDO_) {
        //printf("In arduinoDO_\n");
        sprintf(temp,  "DIGITS:SET:");
                getUIntDigitalParam(function, &value, 0x7);
                for (i=0; i<NUM_IO_BITS; i++) {
                        if (value & 0x1){
                                strcat(temp, "1:");
                        }
                        else{
                                strcat(temp, "0:");
                        }
                        value = value >> 1;
        }

                int len = strlen(temp);
                temp[len-1] = '\0';

#ifdef DEBUG
                //printf("value=0x%x, mask=0x%x\n", value, mask);
                //printf("send: %s\n", temp);
#endif
                status = sendOnlyLock(temp);
    }

        callParamCallbacks(0);
        if (status == asynSuccess) {
            asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
             "%s:%s, port %s, wrote  value=0x%x, mask=0x%x\n",
             driverName, functionName, this->portName, value, mask);
        }
        else {
        asynPrint(pasynUser, ASYN_TRACE_ERROR,
             "%s:%s, port %s, ERROR writing  value=0x%x, mask=0x%x,status=%d\n",
             driverName, functionName, this->portName,  value, mask,  status);
  }

  return status;
}

void asynArduinoController::report(FILE *fp, int level)
{
        int channel;
    double ao, ai;
    unsigned bo, bi;

    fprintf(fp, "driver:%s, portName:%s \n",driverName, this->portName);

        getUIntDigitalParam(arduinoDO_, &bo, 0x7);
        getUIntDigitalParam(arduinoDI_, &bi, 0x7);

        fprintf(fp, "BO:%3o, BI:%3o\n", bo, bi );
    for (channel=0; channel < maxAddr; channel++) {
        if (level > 0)
        {
            getDoubleParam(channel,  arduinoAO_, &ao);
            getDoubleParam(channel,  arduinoAI_, &ai);
                        fprintf(fp, "channel:%d, AO:%.2f, AI:%.2f\n",channel, ao, ai);
        }
    }
}

asynStatus asynArduinoController::sendReceive(const char * outputBuffer, char * inputBuffer, unsigned int inputSize)
{
/*
        printf("output: %s\n", outBuffer);

        if (strncmp(outBuffer, "VOLTS:GET?", strlen("VOLTS:GET?"))){
                strcpy(inputBuffer, "VOLTS:GET:1.23:2.34:3.56");
        }
        else if (strncmp(outBuffer, "DIGITS:GET?", strlen("DIGITS:GET?"))){
                strcpy(inputBuffer, "DIGTIS:GET:0:1:0");
        }
        else{
                sprintf(inputBuffer, "SendBack: %s", outBugger);
        }

        return asynSuccess;
*/
        size_t nwrite, nread;
        asynStatus status;
        int eomReason;
        // const char *functionName="sendReceive";

        status = pasynOctetSyncIO->writeRead(pasynUserController_,
                outputBuffer, strlen(outputBuffer), inputBuffer, inputSize,
                DEFAULT_TIMEOUT, &nwrite, &nread, &eomReason);

  return status;

}

asynStatus asynArduinoController::sendOnly(const char *outputBuff)
{
/*      printf("output: %s\n", outputBuff);
        return asynSuccess;
*/
        size_t nwrite;
        asynStatus status;
        // const char *functionName="sendOnly";
        status = pasynOctetSyncIO->write(pasynUserController_, outputBuff,
                                strlen(outputBuff), DEFAULT_TIMEOUT, &nwrite);
        return status ;

}

asynStatus asynArduinoController::sendOnlyLock(const char *outputBuff)
{
    asynStatus status;
    baseMutex->lock();
    status = sendOnly(outputBuff);
    baseMutex->unlock();
    return status;
}

asynStatus asynArduinoController::sendReceiveLock(const char *outputBuff, char *inputBuff, unsigned int inputSize)
{
    asynStatus status;
    if (inputSize > 0) inputBuff[0] = '\0';
    baseMutex->lock();
    status = sendReceive(outputBuff, inputBuff, inputSize);
    baseMutex->unlock();
    return status;
}

void asynArduinoController::shutdown(){
      lock();
      shuttingDown_ = 1;
      unlock();
}

void asynArduinoController::arduinoPoller()
{
        static const char *functionName = "arduinoPoller";

    int addr;
    asynStatus status;
    double ai[3];
    double aiold[3];
        epicsUInt32 biOld, bi;
        int bit[3];

    while(1) {

        lock();
        if (shuttingDown_) {
                unlock();
                break;
        }

        sprintf(inputBuffer,"VOLTS:GET?");
            //printf("%s\n", inputBuffer);
        status = sendReceiveLock(inputBuffer, pollInputBuffer, sizeof(pollInputBuffer));
        //printf("%s\n", pollInputBuffer);
                sscanf(pollInputBuffer, "VOLTS:GET:%lf:%lf:%lf", &ai[2], &ai[1], &ai[0]);
        //printf("ai0:%lf,ai1:%lf,ai2:%lf\n", ai[0], ai[1], ai[2]);
                for (addr = 0; addr < NUM_ANALOG_IN; addr++){
                        getDoubleParam(addr, arduinoAI_, &aiold[addr]);
                if (aiold[addr] != ai[addr]){
                                setDoubleParam(addr, arduinoAI_, ai[addr]);
                callParamCallbacks(addr);
             }
         }

        getUIntDigitalParam(arduinoDI_, &biOld, 0x7);
                bi = 0;
        sprintf(inputBuffer,"DIGITS:GET?");
        status = sendReceiveLock(inputBuffer, pollInputBuffer, sizeof(pollInputBuffer));
        //printf("%s\n", pollInputBuffer);
        sscanf(pollInputBuffer, "DIGITS:GET:%d:%d:%d", &bit[0], &bit[1],&bit[2]);
                for (addr = 0; addr < NUM_IO_BITS; addr++){
                        bi = bi << 1;
                        if (bit[2-addr]){
                                bi = bi | 0x1;
                        }
                        else{
                                bi = bi & 0x6;
                        }
            //printf("%d->0x%x\n",2-addr, bi);
                }
        //printf("b0:%d,b1:%d,b2:%d\n", bit[0],bit[1],bit[2]);
        //printf("Old: 0x%x New: 0x%x\n", biOld, bi);
                if (biOld != bi){
                setUIntDigitalParam(arduinoDI_, bi , 0x7);
            callParamCallbacks(0);
         }

        if (shuttingDown_) {
          unlock();
          break;
        }

        unlock();

        /* wait here for the next poll
           waiting may be interrupted by pollEvent or interrupt messages*/
                //epicsThreadSleep(2.0);
                epicsThreadSleep(pollPeriod_);
        }
} /* End while */

void asynArduinoController::callPoller(void *drvPvt)
{
        asynArduinoController *pController = (asynArduinoController*)drvPvt;
    pController->arduinoPoller();
}

asynStatus asynArduinoController::startPoller(double pollPeriod)
{
        char threadName[20];

    pollPeriod_  = pollPeriod;

    sprintf(threadName, "thead-%s", "arduinoPoller");
    printf("call startPoller .... \n");
    epicsThreadCreate(threadName,
            epicsThreadPriorityMedium,  epicsThreadGetStackSize(epicsThreadStackMedium),
           (EPICSTHREADFUNC)&asynArduinoController::callPoller, (void *) this);
  return asynSuccess;
}

extern "C" int asynArduinoControllerConfig(
                const char *portName,
                const char *serverPortName,
                int nChannels,
                int nParams,
                int interfaceMask,
                int interruptMask)

{
    asynArduinoController *pController = new asynArduinoController(portName,
            serverPortName, nChannels, nParams, interfaceMask, interruptMask);
    pController->startPoller(POLL_TIME);
    return(asynSuccess);
}

extern "C"
{

static const iocshArg asynArduinoControllerArg0 = {"asyn port name", iocshArgString};
static const iocshArg asynArduinoControllerArg1 = {"server port name", iocshArgString};
static const iocshArg asynArduinoControllerArg2 = {"number of channels", iocshArgInt};
static const iocshArg asynArduinoControllerArg3 = {"nummber of params", iocshArgInt};
static const iocshArg asynArduinoControllerArg4 = {"interface Mask", iocshArgInt};
static const iocshArg asynArduinoControllerArg5 = {"interrupt Mask", iocshArgInt};
static const iocshArg * const asynArduinoControllerArgs[6] = {&asynArduinoControllerArg0,
                                                  &asynArduinoControllerArg1,
                                                  &asynArduinoControllerArg2,
                                                  &asynArduinoControllerArg3,
                                                  &asynArduinoControllerArg4,
                                                  &asynArduinoControllerArg5 };
static const iocshFuncDef asynArduinoControllerFuncDef = {"asynArduinoControllerConfig", 6, asynArduinoControllerArgs};
static void  asynArduinoControllerCallFunc(const iocshArgBuf *args)
{
    asynArduinoControllerConfig(args[0].sval, args[1].sval, args[2].ival, args[3].ival, args[4].ival, args[5].ival);
}

static void asynArduinoRegister(void)
{
    iocshRegister(&asynArduinoControllerFuncDef,  asynArduinoControllerCallFunc);
}

epicsExportRegistrar(asynArduinoRegister);
}

添加 arduinoSupport.dbd 文件,其内容如下:

/* cat arduinoSupport.dbd /*
registrar(asynArduinoRegister)

编辑同一目录下的Makefile文件,添加所需的数据库定义文件和库文件 

TOP=../..

include $(TOP)/configure/CONFIG
#----------------------------------------
#  ADD MACRO DEFINITIONS AFTER THIS LINE
#=============================

#=============================
# Build the IOC application

PROD_IOC = asynArduino
# asynArduino.dbd will be created and installed
DBD += asynArduino.dbd

# asynArduino.dbd will be made up from these files:
asynArduino_DBD += base.dbd

# Include dbd files from all support applications:
asynArduino_DBD += asyn.dbd
asynArduino_DBD += arduinoSupport.dbd
asynArduino_DBD += drvAsynSerialPort.dbd
asynArduino_DBD += drvAsynIPPort.dbd


# Add all the support libraries needed by this IOC
asynArduino_LIBS += asyn

asynArduino_SRCS += arduino.cpp
# asynArduino_registerRecordDeviceDriver.cpp derives from asynArduino.dbd
asynArduino_SRCS += asynArduino_registerRecordDeviceDriver.cpp

# Build the main IOC entry point on workstation OSs.
asynArduino_SRCS_DEFAULT += asynArduinoMain.cpp
asynArduino_SRCS_vxWorks += -nil-

# Add support from base/src/vxWorks if needed
#asynArduino_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary

# Finally link to the EPICS Base libraries
asynArduino_LIBS += $(EPICS_BASE_IOC_LIBS)

#===========================

include $(TOP)/configure/RULES
#----------------------------------------
#  ADD RULES AFTER THIS LINE

4、切换到目录asynArduino/asynArduinoApp/Db下,编写四个模板文件:

1)aiFloat64.template:

record(ai, "$(P)$(R)AI$(N)") {
    field(DTYP,"asynFloat64")
    field(INP,"@asyn($(PORT) $(OFFSET))ARDUINO_AI_STRING")
    field(HOPR,"$(HOPR)")
    field(LOPR,"$(LOPR)")
    field(PREC,"$(PREC)")
    field(SCAN,"$(SCAN)")
}

2)ao.template 

record(ao, "$(P)$(R)AO$(N)") {
    field(DTYP,"asynFloat64")
    field(OUT,"@asyn($(PORT),$(OFFSET),1.0)ARDUINO_AO_STRING")
    field(HOPR,"$(HOPR)")
    field(LOPR,"$(LOPR)")
    field(PREC,"$(PREC)")
}

 3)bi_bit.template

record(bi,"$(P)$(R)BI$(N)") {
    field(DTYP,"asynUInt32Digital")
    field(INP,"@asynMask($(PORT),0,$(MASK), 1.0)ARDUINO_DI_STRING")
    field(SCAN,"$(SCAN)")
    field(ZNAM,"$(ZNAM)")
    field(ONAM,"$(ONAM)")
    field(ZSV,"$(ZSV)")
    field(OSV,"$(OSV)")
}

4) bo_bit.template

record(bo,"$(P)$(R)BO$(N)") {
    field(DTYP,"asynUInt32Digital")
    field(OUT,"@asynMask($(PORT),0,$(MASK),1.0)ARDUINO_DO_STRING")
    field(ZNAM,"$(ZNAM)")
    field(ONAM,"$(ONAM)")
}

 5)编辑相同目录下的Makefile文件:

....
DB += bo_bit.template
DB += bi_bit.template
DB += aiFloat64.template
DB += ao.template
...

5、切换到本IOC的顶层目录,并且执行make命令,编译整个程序: 

root@lubancat:/usr/local/EPICS/program/asynArduino# make
make -C ./configure install
make[1]: Entering directory '/usr/local/EPICS/program/asynArduino/configure'
...
make[2]: Leaving directory '/usr/local/EPICS/program/asynArduino/iocBoot/iocasynArduino'
make[1]: Leaving directory '/usr/local/EPICS/program/asynArduino/iocBoot'

6、切换到IOC启动目录 iocBoot/iocasynArduino/

root@lubancat:/usr/local/EPICS/program/asynArduino# cd iocBoot/iocasynArduino/
root@lubancat:/usr/local/EPICS/program/asynArduino/iocBoot/iocasynArduino# pwd
/usr/local/EPICS/program/asynArduino/iocBoot/iocasynArduino

编写四个替换文件:

 1)ais.substitutions

file "../../db/aiFloat64.template" { pattern
{P,         R,        N,     PORT,    OFFSET,   LOPR, HOPR, PREC,   SCAN}
{TEST:,    ARDUINO:,   0,       AA        0,       0.0  5.0   3,      "I/O Intr"}
{TEST:,    ARDUINO:,   1,       AA        1,       0.0  5.0   3,      "I/O Intr"}
{TEST:,    ARDUINO:,   2,       AA        2,       0.0  5.0   3,      "I/O Intr"}
}

 2)aos.substitutions

file "../../db/ao.template" { pattern
{P,           R,        N     PORT, OFFSET,    LOPR, HOPR, PREC}
{TEST:,    ARDUINO:,    0,    AA,     0,        0.0,    5.0,     3}
{TEST:,    ARDUINO:,    1,    AA,     1,        0.0,    5.0,     3}
{TEST:,    ARDUINO:,    2,    AA,     2,        0.0,    5.0,     3}
}

3) bis.substitutions


file "../../db/bi_bit.template" { pattern
{P,           R,         N,  PORT,             MASK,      ZNAM,   ONAM,  ZSV,       OSV,    SCAN}
{TEST:,       ARDUINO:,   0,  AA,               0x1,        Low,    High,  NO_ALARM,  MAJOR,  "I/O Intr"}
{TEST:,       ARDUINO:,   1,  AA,               0x2,        Low,    High,  NO_ALARM,  MAJOR,  "I/O Intr"}
{TEST:,       ARDUINO:,   2,  AA,               0x4,        Low,    High,  NO_ALARM,  MAJOR,  "I/O Intr"}
}

 4) bos.substitutions

file "../../db/bo_bit.template" { pattern
{P,          R,   N       PORT,   MASK,        ZNAM,   ONAM}
{TEST:,     ARDUINO:,   0,       AA,     0x1,        Low,    High}
{TEST:,     ARDUINO:,   1,       AA,     0x2,        Low,    High}
{TEST:,     ARDUINO:,   2,       AA,     0x4,        Low,    High}
}

5) 编辑启动脚本st.cmd,添加硬件连接语句以及记录加载语句: 

#!../../bin/linux-x86_64/asynArduino

#- You may have to change asynArduino to something else
#- everywhere it appears in this file

< envPaths

cd "${TOP}"

## Register all support components
dbLoadDatabase "dbd/asynArduino.dbd"
asynArduino_registerRecordDeviceDriver pdbbase

# Use the following commands for serial RTU or ASCII
#drvAsynSerialPortConfigure(const char *portName,
#                           const char *ttyName,
#                           unsigned int priority,
#                           int noAutoConnect,
#                           int noProcessEos);
drvAsynSerialPortConfigure("Arduino", "/dev/ttyACM0", 0, 0, 0)
asynSetOption("Arduino",0,"baud","9600")
asynSetOption("Arduino",0,"parity","none")
asynSetOption("Arduino",0,"bits","8")
asynSetOption("Arduino",0,"stop","1")
asynOctetSetInputEos( "Arduino",0,"\r\n")
asynOctetSetOutputEos("Arduino",0,"\r\n")

asynArduinoControllerConfig("AA", "Arduino", 3, 0, 0, 0)

## Load record instances
#dbLoadRecords("db/xxx.db","user=xxx")

cd "${TOP}/iocBoot/${IOC}"
dbLoadTemplate("bos.substitutions")
dbLoadTemplate("bis.substitutions")
dbLoadTemplate("ais.substitutions")
dbLoadTemplate("aos.substitutions")

iocInit

7、在启动目录中执行../../bin/linux-aarch64/asynArduino st.cmd 启动这个IOC,并且用dbl命令查看已经加载的记录。

root@lubancat:/usr/local/EPICS/program/asynArduino/iocBoot/iocasynArduino# ../../bin/linux-aarch64/asynArduino st.cmd
#!../../bin/linux-x86_64/asynArduino
< envPaths
epicsEnvSet("IOC","iocasynArduino")
epicsEnvSet("TOP","/usr/local/EPICS/program/asynArduino")
epicsEnvSet("SUPPORT","/usr/local/EPICS/synApps/support")
epicsEnvSet("ASYN","/usr/local/EPICS/synApps/support/asyn")
epicsEnvSet("EPICS_BASE","/usr/local/EPICS/base")
cd "/usr/local/EPICS/program/asynArduino"
...
iocInit
Starting iocInit
############################################################################
## EPICS R7.0.7
## Rev. 2024-05-31T11:45+0800
## Rev. Date build date/time:
############################################################################
iocRun: All initialization complete
## Start any sequence programs
#seq sncxxx,"user=blctrl"
epics> dbl
TEST:ARDUINO:AI0
TEST:ARDUINO:AI1
TEST:ARDUINO:AI2
TEST:ARDUINO:AO0
TEST:ARDUINO:AO1
TEST:ARDUINO:AO2
TEST:ARDUINO:BI0
TEST:ARDUINO:BI1
TEST:ARDUINO:BI2
TEST:ARDUINO:BO0
TEST:ARDUINO:BO1
TEST:ARDUINO:BO2

 8、启动窗口文件,查看各记录的状态,并且记录在DO和AO尝试输入,并且查看相应状态。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值