Enter Your Electronics & Design Project for a chance to win a Grand Prize for Originality, a Tool Set, and a $100 Shopping Cart! | 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?
Top Comments