2013-07-16 1 views
0

Я тестирую функцию vanilla viWrite() и понял, что она не возвращает код ошибки при передаче в недопустимой командной строке. Я нахожу это немного странным ... конечно, реализация должна обнаружить это событие.NI VISA и viWrite не обнаруживает ошибок команды

Вот небольшой тест я использовал, чтобы продемонстрировать это ... (это просто тестовый код, поэтому он не будет идеально :))

#include <visa.h> 
#include <cstring> 
#include <iostream> 

#define VIBUF_LEN 255 

static ViChar viBuf[VIBUF_LEN]; 

void MyWrite(ViSession sess, char const *cmd) 
{ 
    ViStatus status; 
    ViUInt32 rcount; 

    strncpy_s(viBuf, cmd, VIBUF_LEN); 
    status = viWrite(sess, (ViBuf)viBuf, strlen(viBuf), &rcount); 
    if (status < VI_SUCCESS) 
    { 
     std::cout << "Failed to write!\n"; 
     exit(-1); 
    } 
} 

std::string MyRead(ViSession sess) 
{ 
    ViStatus status; 
    ViUInt32 rcount; 

    status = viRead(sess, (ViBuf)viBuf, VIBUF_LEN, &rcount); 
    if (status < VI_SUCCESS) 
    { 
     std::cout << "Failed to read 1!\n"; 
     exit(-1); 
    } 
    else if (rcount >= VIBUF_LEN) 
    { 
     std::cout << "Failed to read 2!\n"; 
     exit(-1); 
    } 
    else if (!rcount) 
    { 
     std::cout << "Failed to read 3!\n"; 
     exit(-1); 
    } 

    viBuf[rcount] = NULL; 
    return std::string(viBuf); 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    ViStatus status; 
    ViSession mVisaDefaultRM; 
    ViSession mVisaInst; 

    status = viOpenDefaultRM(&mVisaDefaultRM); 
    if (status == VI_SUCCESS) 
    { 
     strncpy_s(viBuf, "GPIB0::1::INSTR", VIBUF_LEN); 
     status = viOpen(mVisaDefaultRM, viBuf, VI_NULL, VI_NULL, &mVisaInst); 
    } 

    if (status < VI_SUCCESS) 
    { 
     std::cout << "Failed to initialise!\n"; 
     exit(-1); 
    } 

    viClear(mVisaInst); 
    MyWrite(mVisaInst, "*CLS;"); 
    MyWrite(mVisaInst, "*RST;"); 
    MyWrite(mVisaInst, "*SRE 0;"); 
    MyWrite(mVisaInst, "*ESE 0;"); 
    MyWrite(mVisaInst, "CRAP;"); /* Wow really!? */ 
    MyWrite(mVisaInst, "*ESR?;"); 
    std::string str = MyRead(mVisaInst); 
    std::cout << "ESR is " << str.c_str() << "\n"; 

    std::cout << "END\n"; 
    getchar(); 

    return 0; 
} 

Программа выводит следующее:

ESR is +32 
END 

Итак, запись команды SCPI «CRAP;» определенно будет помечен как ошибка устройства.

Это заставило меня подумать, а ... Я не включил бит ESE, чтобы этот бит мог быть помечен в STB. Поэтому я делаю это:

MyWrite(mVisaInst, "*ESE 255;"); 
//      ^^^ 
//      A bit of a sledge hammer but should do the job 

Плохая команда все еще не обнаружена.

Хорошо, так что, возможно, потребуется включить SRQs ... возможно, потребности библиотек ВИЗА как это позволило справиться с этим ...

Так что я это сделать:

MyWrite(mVisaInst, "*SRE 255;"); 
//      ^^^ 
//      A bit of a sledge hammer but should do the job 

Нет, никакой разницы. Он все еще не обнаруживает плохую команду.

Является ли эта стандартная VISA? Должна ли она работать так? Означает ли это, что, если я хочу обнаружить эти ошибки, мне всегда нужно включить событие VI_EVENT_SERVICE_REQ и поэтому viWaitOnEvent() после записи? Я бы подумал, что ваниль viWrite() обнаружит это для меня ??

+2

не возможно, что viWrite просто заботится о _writing_? Я имею в виду, что дело не в том, что команда не имеет смысла, что писать не удалось. Или сказать иначе: предположим, что я ввожу опечатку в этот комментарий, оставляя ее все еще успешно. – stijn

+0

да мог быть! +1. Я новичок в визе, и я предполагал, что она выполняет некоторые работы за кулисами, чтобы проверить наличие ошибок, но то, что вы говорите, имеет больше смысла, поскольку оно должно быть независимым от устройства, хотя ESR несколько стандартизирован. Хм ... hastle ... Я хочу иметь возможность обнаруживать такие ошибки без прерывания любых команд, которые я отправляю и т. Д., Но без необходимости полагаться на таймаут, если не происходит никаких ошибок ... насколько хорошо вы знаете библиотеку виз? – Jimbo

+0

Я думаю, вы правы. Код возврата ошибки должен быть просто ошибкой на стороне клиента или если устройство не отвечает вообще или правильно квитированию, но не более того. Если вы хотите опубликовать его в качестве ответа, я подниму и соглашусь. Спасибо за указание на это! – Jimbo

ответ

2

viWrite просто заботится о написании (см. Ni Visa Programmers Reference), что означает, что он возвращает ошибку только тогда, когда есть истинный сбой связи (например, тайм-аут или кто-то отсоединит кабель и т. Д.). Это стандартно для низкоуровневых функций ввода/вывода (сокеты, последовательные порты, ... все работают таким образом).

Это означает, что, если есть ошибка удаленного устройства, вам придется как-то это запросить. Я не знаком с VISA, поэтому я не уверен, что лучший способ добиться этого. Это что-то вроде того, о чем вы говорите (события), или, может быть, вы можете напрямую запросить устройство? (возможно, вы можете выполнить команду, которая говорит «дайте мне свой статус», а затем viRead ответ?)

+0

Спасибо stijn.Не уверен, что лучший способ решить это, так как кажется, что некоторые команды не генерируют «успешный» сигнал, который я могу использовать в качестве SRQ. Я думаю, возможно, SPOLL, не уверен. Приветствия за помощь – Jimbo

Смежные вопросы