Comments (5)
I think, that your example is wrong, because 1
has 1 dimension and 2!4
has 2 dimensions and there is not possible to create range :
between different number of dimensions.
I will update documentation for this soon.
from scpi-parser.
Hi,
I completely had the syntax wrong. Should've been READ? (@1,2,4)
. A better example would be MEAS:VOLT (@1,3,4:6)
, taken from SCPI99, Vol 1 Ch. 8.3.2 "Expressions - Channel Lists".
from scpi-parser.
OK, I don't have much time to write better documentation, so here are just small hints.
In handler of your command, read channel list as parameter using SCPI_Parameter
.
scpi_parameter_t channel_list_param;
// get channel list
if (SCPI_Parameter(context, &channel_list_param, TRUE)) {
scpi_expr_result_t res;
scpi_bool_t is_range,
int32_t values_from[4];
int32_t values_to[4];
size_t dimensions;
// this is valid usage and it gets only real number of dimensions for the first item (index 0)
res = SCPI_ExprChannelListEntry(context, &channel_list_param, 0, &is_range, NULL, NULL, 0, &dimensions);
// this will fill values
// if is_range, then both values_from and values_to are filled
// dimensions represents number of items in this array. This number is always
// number of dimensions and can be larger then size of provided array, but provided array
// is filled only up to its size.
res = SCPI_ExprChannelListEntry(context, &channel_list_param, 0, &is_range, values_from, values_to, 4, &dimensions);
}
You must iterate over all entries in the expression by changing index and chacking the result. If result is SCPI_EXPR_OK
then all values are valid. If the result is SCPI_EXPR_ERROR
, there was an error and you should stop handling this command.
If the result is SCPI_EXPR_NO_MORE
then there are no more Entries in the list.
For channel list (@1,3,4:6)
, this will be result
- for index 0,
is_range = false
,values_from[0] = 1
,dimensions = 1
- for index 1,
is_range = false
,values_from[0] = 3
,dimensions = 1
- for index 2,
is_range = true
,values_from[0] = 4
,values_to[0] = 6
,dimensions = 1
- for index 3, result is
SCPI_EXPR_NO_MORE
from scpi-parser.
I coded a rather long example which handles different cases for channel numbers.
It works for (up to) 2 dimensions so far.
SCPI Vol says to parse ranges in order.
One enters ranges like this: (@rs!cs:re!ce)
, concatenating of ranges does work, too.
rs means "row start", re "row end", cs "column start", ce "column end".
Examples:
(@1!1:3!2)
would be 1!1, 1!2, 2!1, 2!2, 3!1, 3!2.
(@3!1:1!3)
would be 3!1, 3!2, 3!3, 2!1, 2!2, 2!3, ... 1!3.
In this example the whole channel list is written to array[]
of dimensions maxrow
x maxcol
. Last values of array are {0, 0}. I introduced a datatype at the beginning to hold a value for row and column.
Hope this helps someone. Suggestions welcome!
struct _scpi_channel_value_t {
int32_t row;
int32_t col;
};
typedef struct _scpi_channel_value_t scpi_channel_value_t;
/**
* @brief
* parses lists
* channel numbers > 0.
* no checks yet.
* valid: (@1), (@3!1:1:3,4), ...
*
* @param channel_list channel list, compare to SCPI99 Vol 1 Ch. 8.3.2
*/
static scpi_result_t TEST_Chanlst ( scpi_t *context )
{
scpi_parameter_t channel_list_param;
#define maxrow 2 //maximum number of rows
#define maxcol 6 //maximum number of columns
#define maxdim 2 //maximum number of dimensions
scpi_channel_value_t array[maxrow * maxcol]; //array which holds values in order (2D)
size_t chanlst_idx; //index for channel list
size_t arr_idx; //index for array
size_t n, m = 1; //counters for row (n) and columns (m)
// get channel list
if ( SCPI_Parameter ( context, &channel_list_param, TRUE ) ) {
scpi_expr_result_t res;
scpi_bool_t is_range;
int32_t values_from[maxdim];
int32_t values_to[maxdim];
size_t dimensions;
bool for_stop_row = false; //true if iteration for rows has to stop
bool for_stop_col =false; //true if iteration for columns has to stop
int32_t dir_row = 1; //direction of counter for rows, +/-1
int32_t dir_col = 1; //direction of counter for columns, +/-1
// the next statement is valid usage and it gets only real number of dimensions for the first item (index 0)
if(!SCPI_ExprChannelListEntry ( context, &channel_list_param, 0, &is_range, NULL, NULL, 0, &dimensions )) {
chanlst_idx = 0; //call first index
arr_idx = 0; //set arr_idx to 0
do { //if valid, iterate over channel_list_param index while res == valid (do-while cause we have to do it once)
res = SCPI_ExprChannelListEntry ( context, &channel_list_param, chanlst_idx, &is_range, values_from, values_to, 4, &dimensions );
if (is_range == false) { //still can have multiple dimensions
if (dimensions == 1) {
//here we have our values
//row == values_from[0]
//col == 0 (fixed number)
//call a function or something
array[arr_idx].row = values_from[0];
array[arr_idx].col = 0;
} else if (dimensions == 2) {
//here we have our values
//row == values_fom[0]
//col == values_from[1]
//call a function or something
array[arr_idx].row = values_from[0];
array[arr_idx].col = values_from[1];
} else {
return SCPI_RES_ERR;
break;
}
arr_idx++; //inkrement array where we want to save our values to, not neccessary otherwise
} else if (is_range == true) {
if (values_from[0] > values_to[0]) {
dir_row = -1; //we have to decrement from values_from
} else { //if (values_from[0] < values_to[0])
dir_row = +1; //default, we increment from values_from
}
//iterating over rows, do it once -> set for_stop_row = false
//needed if there is channel list index isn't at end yet
for_stop_row = false;
for (n = values_from[0]; for_stop_row == false; n +=dir_row) {
//usual case for ranges, 2 dimensions
if (dimensions == 2) {
if (values_from[1] > values_to[1]) {
dir_col = -1;
} else if (values_from[1] < values_to[1]) {
dir_col = +1;
}
//iterating over columns, do it at least once -> set for_stop_col = false
//needed if there is channel list index isn't at end yet
for_stop_col = false;
for (m = values_from[1]; for_stop_col == false; m +=dir_col) {
//here we have our values
//row == n
//col == m
//call a function or something
array[arr_idx].row = n;
array[arr_idx].col = m;
arr_idx++;
if (m == values_to[1]) {
//endpoint reached, stop column for-loop
for_stop_col = true;
}
}
//special case for range, example: (@2!1)
} else if (dimensions == 1) {
//here we have values
//row == n
//col == 0 (fixed number)
//call function or sth.
array[arr_idx].row = n;
array[arr_idx].col = 0;
arr_idx++;
}
if (n == values_to[0]){
//endpoint reached, stop row for-loop
for_stop_row = true;
}
}
} else {
return SCPI_RES_ERR;
break;
}
//increase index
chanlst_idx++;
} while ( SCPI_EXPR_OK == SCPI_ExprChannelListEntry ( context, &channel_list_param, chanlst_idx, &is_range, values_from, values_to, 4, &dimensions ) ) ;
//while checks, whether incremented index is valid
}
//do something at the end if needed
array[arr_idx].row = 0;
array[arr_idx].col = 0;
}
return SCPI_RES_OK;
}
from scpi-parser.
Nice example. I will integrate this to documentation and to examples.
Maybe, there can be some helper function for 1 dimension and 2 timensions to do this for you.
from scpi-parser.
Related Issues (20)
- C++ compilation error due to NULL being a long int HOT 1
- ip set HOT 1
- check if osThreadCreate() successful HOT 8
- Possible to have multiple, independent scpi session? HOT 4
- Example of Optional keywords/Related API HOT 1
- introducing a help command HOT 5
- problem talking with sigrok HOT 5
- USE_FULL ERROR LIST report "Unknow Error" for all XE errors HOT 2
- Termination for SCPI commands HOT 3
- arm cross-compilation requires additional flags HOT 2
- Compile error when compiling with C++17 HOT 1
- vxi11.h missing ??
- Port to Arduino
- scpi-parser support on windows? HOT 1
- Documentation out of date?
- How the MAV bit is setting in Status register. HOT 1
- Handle errors from the read/write method HOT 11
- [Feature request] Add support to handle numerical values in choice list
- TEST_Chanlst upper limit fails HOT 1
- Parsing decimal values HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from scpi-parser.