Test Instrumentation

Enter Your Electronics & Design Project for a chance to win a Grand Prize for Originality, a Tool Set, and a $100 Shopping Cart!

Back to The Project14 homepage

Project14 Home
Monthly Themes
Monthly Theme Poll

 

I'm building a SCPI electronics lab instrument for Linux.

This post builds up on part 4: TCP/IP SCPI and Instrument Service. I've now completed both read and write functionality.

 

What Was Missing from post 4?

 

The previous post had both Instrument and SCPI services working together but didn't support reading inputs. That's completed now.

Both the SCPI Service and the Instrument Service can handle reads from the PiFace Digital inputs.

 

Here's the read command:

 

    {.pattern = "DIGItal:INPut#?", .callback = SCPI_DigitalInputQ,},

 

.... and the read handler:

 

  /**
   * get digital input of the PiFace


   *
   * Return SCPI_RES_OK
   *
   */
  static scpi_result_t SCPI_DigitalInputQ(scpi_t * context) {
    int32_t numbers[1];
    // retrieve the output. Can be 0 - 7
    SCPI_CommandNumbers(context, numbers, 1, 0);
    if (! ((numbers[0] > -1) && (numbers[0] < 8) )) {
      SCPI_ErrorPush(context, SCPI_ERROR_INVALID_SUFFIX);
      return SCPI_RES_ERR;
    }

  // parse the reply
  SCPI_ResultBool(context, (digitalInput('i', numbers[0]) > 0) );
  return SCPI_RES_OK;
}

 

I've extracted the instrument dependent code because later on I may also implement a read on the output pins ...

 

int32_t digitalInput(char cIO, int32_t pin) {
  memset(instrument_payload, '.', sizeof(instrument_payload));
  instrument_payload[0] = 'r';
  instrument_payload[1] = 'e';
  instrument_payload[2] = 'a';
  instrument_payload[3] = 'd';
  (instrument_payload[4] = '0' + pin); // only works if the 0 - 7 characters in the character set are consecutive. todo: Sue me.
  sendToInstrument(instrument_payload, sizeof(instrument_payload));
  return (instrument_payload[5] - '0');  // only works if the 0 - 1 characters in the character set are consecutive. todo: Sue me.
}

 

Here's how the instrument handles it. Very simple, now that I have a PifaceDigital class that can deal with hardware:

 

        if (x.compare(0, 4, "read") == 0) {
          uint8_t bitnum = std::stoi(x.substr(4, 1));
          int value = pfd_read(bitnum, PifaceDigital::INPUT, pf);


          x.replace(5,1, value? "1" : "0");
        } else if (x.compare(0, 5, "write") == 0){

 

The write part was explained in the previous post.

 

Input values can be retrieved by sending this SCPI command:

 

:DIGI:INPx?

 

In the above terminal session, I sent 2 requests. The first time, I did not push switch S0 on the PiFace Digital 2 hat. The second time I did.

 

With all of the functional code working, I can concentrate on the next step: creating the Daemon wrappers to run the programs when my Raspberry Pi is powered on ...

 

 

note to @self: todo: create 2 dependent linux daemons, extend the LABView driver to include the set/get commands.

note to @others: todo: the PiFace Digital 2 SPI expander supports interrupts. Can you take advantage of them and incorporate them in the Raspberri Pi firmware and LABView drivers?

 

related blog
SCPI on a Linux Board - Letter of Intent

SCPI on a Linux Board - Part 1: Proof of Concept

SCPI on a Linux Board - Part 2a: PiFace Digital C programming

SCPI on a Linux Board - Part 2b: PiFace Digital C++ programming
SCPI on a Linux Board - Part 3: TCP/IP Socket C++ programming
SCPI on a Linux Board - Part 4: TCP/IP SCPI and Instrument Service
SCPI on a Linux Board - Part 4b: TCP/IP SCPI and Instrument Service 100% Working
SCPI on a Linux Board - Part 5a: LabVIEW Driver for LAB Switch: Open, Close and Switch functions

 

I'v attached the latest version of both scpi socket service and piface_digital service