element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Open Arduino
  • Challenges & Projects
  • Project14
  • Open Arduino
  • More
  • Cancel
Open Arduino
Blog Arduino in Test Instrumentation - Part 2: Firmware
  • Blog
  • Forum
  • Documents
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Open Arduino to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Jan Cumps
  • Date Created: 6 Apr 2018 9:13 PM Date Created
  • Views 4282 views
  • Likes 9 likes
  • Comments 8 comments
  • diytestequipch
  • ardexpert
  • openarduinoch
  • scpi
  • arduino_test_instrumentation
Related
Recommended

Arduino in Test Instrumentation - Part 2: Firmware

Jan Cumps
Jan Cumps
6 Apr 2018
image

Open Arduino

Enter Your Project for a chance to win a grand prize for the most innovative use of Arduino or a $200 shopping cart! The Birthday Special: Arduino Projects for Arduino Day!

Back to The Project14 homepage image

Project14 Home
Monthly Themes
Monthly Theme Poll

 

Arduino in Test Instrumentation

 

To celebrate Project 14's birthday, I'm going to make a programmable switch with an Arduino UNO.

This post describes the firmware and SCPI api.

image

 

SCPI Commands

 

The instrument supports the following commands:

CommandDescriptionExample
*IDN?instrument identity

*IDN?

element14,Arduino SCPI Switch,1,0

*RSTreset instrument. Set all switches off*RST
*CLSsame as *RST*CLS
:DIGITAL:SWITCH# ON|OFFturn a switch on or off. 1 based:DIGI:SWIT1 ON
:DIGITAL:SWITCH#?get a switch' status. 1 based

:DIGITAL:SWITCH1?

OFF

 

Firmware

 

Here's a link to the GIST: https://gist.github.com/jancumps/9573730e7bac392efcdbfa24e722bf4d#file-scpiswitch-ino

 

I don' know what's wrong with element14's code highlighter these days, but it fails to show #includes with angle brackets.

The first two lines are:

#include <scpiparser.h>

#include <Arduino.h>

 

#include 
#include 


#define NUMBEROFCHANNELS 2


struct scpi_parser_context ctx;


scpi_error_t identify(struct scpi_parser_context* context, struct scpi_token* command);
scpi_error_t reset(struct scpi_parser_context* context, struct scpi_token* command);
scpi_error_t get_digital_1(struct scpi_parser_context* context, struct scpi_token* command);
scpi_error_t get_digital_2(struct scpi_parser_context* context, struct scpi_token* command);
scpi_error_t set_digital_1(struct scpi_parser_context* context, struct scpi_token* command);
scpi_error_t set_digital_2(struct scpi_parser_context* context, struct scpi_token* command);


bool bDigital [NUMBEROFCHANNELS] = {};
int  iPins [NUMBEROFCHANNELS] = {2,3};


void setup() {
  struct scpi_command* digital;
  int i = 0;
  Serial.begin(38400);
  
  for (i = 0; i < NUMBEROFCHANNELS; i++) {
    pinMode(iPins[i], OUTPUT);
    digitalWrite(iPins[i], LOW);    
  }




  /* First, initialise the parser. */
  scpi_init(&ctx);


  /*
   * After initialising the parser, we set up the command tree.  Ours is
   *
   *  *IDN?         -> identify
   *  *RST          -> reset
   *  :DIGI
   *    :SWIT1    -> channel 1
   *    :SWIT2    -> channel 2
   */
  scpi_register_command(ctx.command_tree, SCPI_CL_SAMELEVEL, "*IDN?", 5, "*IDN?", 5, identify);
  scpi_register_command(ctx.command_tree, SCPI_CL_SAMELEVEL, "*RST", 4, "*RST", 4, reset);
  scpi_register_command(ctx.command_tree, SCPI_CL_SAMELEVEL, "*CLS", 4, "*CLS", 4, reset);


  digital = scpi_register_command(ctx.command_tree, SCPI_CL_CHILD, "DIGITAL", 7, "DIGI", 4, NULL);


  scpi_register_command(digital, SCPI_CL_CHILD, "SWITCH1?", 8, "SWIT1?", 6, get_digital_1);
  scpi_register_command(digital, SCPI_CL_CHILD, "SWITCH2?", 8, "SWIT2?", 6, get_digital_2);


  scpi_register_command(digital, SCPI_CL_CHILD, "SWITCH1", 7, "SWIT1", 5, set_digital_1);
  scpi_register_command(digital, SCPI_CL_CHILD, "SWITCH2", 7, "SWIT2", 5, set_digital_2);




}


void loop() {
  char line_buffer[256];
  unsigned char read_length;


  while(1)   {
    /* Read in a line and execute it. */
    read_length = Serial.readBytesUntil('\n', line_buffer, 256);  
    if(read_length >0)  
      if(line_buffer[read_length-1]=='\r')  // thank you jon clift
        read_length = read_length - 1;    if(read_length > 0)     {
      scpi_execute_command(&ctx, line_buffer, read_length);
    }
  }
}




 


/*
 * Respond to *IDN?
 */
scpi_error_t identify(struct scpi_parser_context* context, struct scpi_token* command) {
  scpi_free_tokens(command);


  Serial.println("Project14,Arduino SCPI Switch,1,0");
  return SCPI_SUCCESS;
}


/*
 * Respond to *RST and *CLS
 */
scpi_error_t reset(struct scpi_parser_context* context, struct scpi_token* command) {
  scpi_free_tokens(command);
  int i = 0;


  for (i = 0; i < NUMBEROFCHANNELS; i++) {
    digitalWrite(iPins[i], LOW);
    bDigital[i] = 0;    
  }
  return SCPI_SUCCESS;
}




scpi_error_t get_digital(int channel, struct scpi_parser_context* context, struct scpi_token* command) {
  if (bDigital[channel] ) {
    Serial.println("ON");
  } else {
    Serial.println("OFF");
   
  }
  scpi_free_tokens(command);
  return SCPI_SUCCESS;  
}




/**
 * get digital 1 status
 */
scpi_error_t get_digital_1(struct scpi_parser_context* context, struct scpi_token* command) {
  return get_digital(0, context, command);
}


/**
 * get digital 2 status
 */
scpi_error_t get_digital_2(struct scpi_parser_context* context, struct scpi_token* command) {
  return get_digital(1, context, command);
}


scpi_error_t set_digital(int channel, struct scpi_parser_context* context, struct scpi_token* command) {
  struct scpi_token* args;
  bool bSuccess = false;
  bool bSwitch = false;


  args = command;
  while(args != NULL && args->type == 0) {
    args = args->next;
  }


  if (args->length == 1) {
    if (args->value[0] == '0') {
      bSuccess = true;
    }
    if (args->value[0] == '1') {
      bSuccess = true;
      bSwitch = true;
    }
  }


  if (args->length == 2) {
    if ((args->value[0] == 'O') || (args->value[0] == 'o')) {
      if ((args->value[1] == 'N') || (args->value[1] == 'n')) {
        bSuccess = true;
        bSwitch = true;
      }    
    }
  }


  if (args->length == 3) {
    if ((args->value[0] == 'O') || (args->value[0] == 'o')) {
      if ((args->value[1] == 'F') || (args->value[1] == 'f')) {
        if ((args->value[2] == 'F') || (args->value[2] == 'f')) {
        bSuccess = true;
        }
      }
    }
  }


  scpi_free_tokens(command);


//  Serial.print("Success: ");
//  Serial.print(bSuccess ? "y" : "n");
//  Serial.print(" channel: ");
//  Serial.print(channel);
//  Serial.print(" pin ");
//  Serial.print(iPins[channel]);
//  Serial.print(" switch ");
//  Serial.print(bSwitch ? "on" : "off");
//  Serial.print("\n");


  if (bSuccess) {    
    digitalWrite(iPins[channel], bSwitch? HIGH : LOW);
    bDigital[channel] = bSwitch;
  }
  
  return bSuccess ? SCPI_SUCCESS : SCPI_COMMAND_NOT_FOUND;
 
}


scpi_error_t set_digital_1(struct scpi_parser_context* context, struct scpi_token* command) {
  return set_digital(0, context, command);
}


scpi_error_t set_digital_2(struct scpi_parser_context* context, struct scpi_token* command) {
  return set_digital(1, context, command);
}

 

It isn't difficult to trace the SCPI commands back to the firmware functions. Not a lot is happening here.

Please check the code. If there's a construct that you have questions about, post a comment and I'll elaborate.

 

If you haven't got the SCPI library installed yet, check the previous post: Arduino in Test Instrumentation - Part 1: SCPI Lib.

 

Related Blog
Arduino in Test Instrumentation - Intro: SCPI Programmable Switch
Arduino in Test Instrumentation - Part 1: SCPI Lib
Arduino in Test Instrumentation - Part 2: Firmware
Arduino in Test Instrumentation - Part 3a: LabVIEW Driver Intitialisation Block
Arduino in Test Instrumentation - Part 3b: LabVIEW Driver Switch Control Block
Arduino in Test Instrumentation - Part 3c: LabVIEW Driver Read Status Block
Arduino in Test Instrumentation - Outro: LabVIEW Example
  • Sign in to reply

Top Comments

  • genebren
    genebren over 7 years ago +3
    Jan, Another nice update to your project. I look forward to following the progress as you move forward. Gene
  • Jan Cumps
    Jan Cumps over 7 years ago +3
    These are the commands supported: *IDN? *RST :DIGITAL:SWITCH1 ON :DIGITAL:SWITCH1 OFF :DIGITAL:SWITCH2 ON :DIGITAL:SWITCH2 OFF :DIGITAL:SWITCH1? :DIGITAL:SWITCH1? :DIGITAL:SWITCH2? :DIGITAL:SWITCH2?
  • jc2048
    jc2048 over 7 years ago +3
    I got that to work, but had to put the library in my own documents folder (thanks, mcb1 , for that hint) and not in the Arduino installation library directory. Now all I need to do is dream up an instrument…
Parents
  • jc2048
    jc2048 over 7 years ago

    image

     

    I got that to work, but had to put the library in my own documents folder (thanks, mcb1, for that hint) and not in the Arduino installation library directory.

     

    Now all I need to do is dream up an instrument for it to control and then build it.

    • Cancel
    • Vote Up +3 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps over 7 years ago in reply to jc2048

    I'm checking my previous blog post. I thought I had documented the location ...

     

    My IDE version is 1.8.1, sketchbook in Documents/Arduino ...

     

    image

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • jc2048
    jc2048 over 7 years ago in reply to Jan Cumps

    You had. It was just me getting it all wrong.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • mcb1
    mcb1 over 7 years ago in reply to Jan Cumps

    Sketches get saved where you want them, but the imported stuff tends to be saved in your user directory.

     

    The issue is if multiple people use the same machine, they all need to download the files, and board info etc.

    IMO it wasn't the best way to handle it.

     

    Mark

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • mcb1
    mcb1 over 7 years ago in reply to Jan Cumps

    Sketches get saved where you want them, but the imported stuff tends to be saved in your user directory.

     

    The issue is if multiple people use the same machine, they all need to download the files, and board info etc.

    IMO it wasn't the best way to handle it.

     

    Mark

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
No Data
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube