Vrekrer / Vrekrer_scpi_parser

Simple SCPI parser for Arduino
MIT License
87 stars 26 forks source link

Projects using Vrekrer_scpi_parser #5

Open Vrekrer opened 4 years ago

Vrekrer commented 4 years ago

If you use Vrekrer_scpi_parser library, please post your project here.

Vrekrer commented 4 years ago

Vrekrer_Voltmeter 14 bit voltimeter with SCPI usb and ethernet interfaces for Arduino https://github.com/Vrekrer/Vrekrer_Voltmeter

Vrekrer commented 4 years ago

Vrekrer_Step_Motor SCPI step motor controler for Arduino https://github.com/Vrekrer/Vrekrer_Step_Motor

codenamezoo commented 4 years ago

https://github.com/codenamezoo/Vrekrer_scpi_parser This branch is now dealing with stepper motor controller using Vrekrer_scpi_parser.

rselec commented 3 years ago

Hi, I'm going to use it for my TinyFanController to implement USB communication. Things are working in general but I have some questions/issues which are also something for doku I think.

  1. What are the define SCPI_MAX_TOKENS for, how could I count how many Tokens I have and what is meant with token?
  2. Where should I overwrite the configuration defines? Defining them in main.cpp gives redefined warnings and won't work and modifying the lib header is not a way, because it is outside the application code.

Many Thanks for your great work!

Edit:

I found the additional doku here: https://github.com/Vrekrer/Vrekrer_scpi_parser/commit/4b0adc857e92f0a2f88aa39773044a722a556c79

Please make sure it's inside the header, I use platform IO. So the question about tokens above is answered, but why is the default value for maximum tokens smaller than for commands? As far as I understand SCPI you have usually (always?) more tokens than commands, because a command is build from one or more tokens and have at least one different.

Vrekrer commented 3 years ago

Hi rselec

Thank you for remembering me about 4b0adc8 I did not merge that branch because I was thinking in putting all the documentation into a wiki. But now you mention platform IO. Do platform IO reads the documentation from the headers? Is 4b0adc8 in the right format for automatic documentation?

About your tokens vs commands question, there are several ways to reuse tokens especially if you implement a lot of writes and queries for your commands. For example the Ethernet_Instrument.ino example uses 7 tokens for 7 commands even if "wasting" 3 tokens in SYSTem:COMMunicate:LAN

You should put #define SCPI_MAX_TOKENS before #include "Vrekrer_scpi_parser.h"

Right now SCPI_MAX_TOKENS to the power of SCPI_ARRAY_SYZE should be smaller than 2^31

rselec commented 3 years ago

Hello Vrekrer,

thanks for the fast response.

No I don't think this is the right format, I would say better use comments according to the doxygen syntax. But to be honest I'm not a professional programmer and not very familiar with the automatic documentation stuff around doxygen and readthedocs. Anyhow some explanation somewhere is always better than nothing ;-) Maybe you could come back to edmundsj for documentation, he sounds quiet experienced.

Ok, I don't thought about token reusage, so both cases are possible and you have to check according to your implementation of commands.

I tried to #define the things in the main before including the header, that results in the ugly warnings below:

Linking .pio\build\sparkfun_promicro16\firmware.elf .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src/Vrekrer_scpi_parser.h:61:7: warning: type 'struct SCPI_Parser' violates one definition rule [-Wodr] class SCPI_Parser { ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.h:61:7: note: a different type is defined in another translation unit class SCPI_Parser { ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src/Vrekrer_scpi_parser.h:79:32: note: the first difference of corresponding definitions is field 'tokens_' char *tokens_[SCPI_MAX_TOKENS]; ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.h:79:32: note: a field of same name but different type is defined in another translation unit char *tokens_[SCPI_MAX_TOKENS]; Checking size .pio\build\sparkfun_promicro16\firmware.elf Building .pio\build\sparkfun_promicro16\firmware.hex ^ lto1.exe: note: array types have different bounds

I don't think it had compiled always with the same definition of SCPI_MAX_TOKENS and SCPI_ARRAY_SYZE. Haven't checked function on real target yet.

Anyhow 2^31 should be enough, I would run out of memory much earlier ;-)

Thanks, Robert

Edit: The #define in the main will not work. If I commend out the `#ifndef SCPI_MAX_COMMANDS

define SCPI_MAX_COMMANDS 20

endif`

sections in your header which I defined myself in the main, it won't compile the lib, see below. That's logic, because the Vrekrer_scpi_parser.cpp never includes something from the main.cpp and therefore never get my definitions.

According to my limited knowledge of C programming (I'm a C++ beginner) I see two possible solutions:

We either need a (separated) Vrekrer_scpi_parser_config.h which is included in the Vrekrer_scpi_parser.cpp before Vrekrer_scpi_parser.h and contains only the user configured definitions. The Vrekrer_scpi_parser_config.h must not be part of the library itself (you can deliver an example of course). It have to be part of the application program. This is similar to the way of the famous marlin 3D printing firmware config (Configuration.h, Configuration_adv.h).

Another idea is to completely get rid of the static memory allocation for the buffers and maybe add necessary parameters to the constructor. But that would be a huge effort, and I doubt that I have the knowledge and experience (and time) to solve such a task.

Compiling .pio\build\sparkfun_promicro16\FrameworkArduino\CDC.cpp.o In file included from .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp:1:0: .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.h:79:17: error: 'SCPI_MAX_TOKENS' was not declared in this scope char *tokens_[SCPI_MAX_TOKENS]; ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.h:81:25: error: 'SCPI_MAX_COMMANDS' was not declared in this scope uint32_t valid_codes_[SCPI_MAX_COMMANDS]; ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.h:82:26: error: 'SCPI_MAX_COMMANDS' was not declared in this scope SCPI_caller_t callers_[SCPI_MAX_COMMANDS]; ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp: In member function 'void SCPI_Parser::AddToken(char*)': .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp:99:39: error: 'tokens_' was not declared in this scope allready_added ^= (strncmp(token, tokens_[i], token_size) == 0); ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp:101:24: error: 'SCPI_MAX_TOKENS' was not declared in this scope if (tokens_size_ < SCPI_MAX_TOKENS) { ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp:105:7: error: 'tokens_' was not declared in this scope tokens_[tokens_size_] = stored_token; ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp: In member function 'uint32_t SCPI_Parser::GetCommandCode(SCPI_Commands&)': .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp:116:13: error: 'SCPI_MAX_TOKENS' was not declared in this scope code *= SCPI_MAX_TOKENS; ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp:126:22: error: 'tokens_' was not declared in this scope while (isupper(tokens_[j][short_length])) short_length++; ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp:127:35: error: 'tokens_' was not declared in this scope size_t long_length = strlen(tokens_[j]); //long token's length ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp: In member function 'void SCPI_Parser::RegisterCommand(char*, SCPI_caller_t)': .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp:193:3: error: 'valid_codes_' was not declared in this scope Compiling .pio\build\sparkfun_promicro16\FrameworkArduino\HardwareSerial.cpp.o valid_codes_[codes_size_] = code; ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp:194:3: error: 'callers_' was not declared in this scope callers_[codes_size_] = caller; ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp: In member function 'void SCPI_Parser::Execute(char*, Stream&)': .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp:204:9: error: 'valid_codes_' was not declared in this scope if (valid_codes_[i] == code) ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp:205:9: error: 'callers_' was not declared in this scope (*callers_[i])(commands, parameters, interface); ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp: In member function 'char* SCPI_Parser::GetMessage(Stream&, const char*)': .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp:234:43: error: 'SCPI_TIMEOUT' was not declared in this scope if ((millis() - last_data_millis) > SCPI_TIMEOUT) { ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp: In member function 'void SCPI_Parser::PrintDebugInfo()': .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp:262:27: error: 'tokens_' was not declared in this scope Serial.println(String(tokens_[i])); ^ .pio\libdeps\sparkfun_promicro16\Vrekrer SCPI parser\src\Vrekrer_scpi_parser.cpp:269:20: error: 'valid_codes_' was not declared in this scope Serial.println(valid_codes_[i]); ^ *** [.pio\build\sparkfun_promicro16\lib811\Vrekrer SCPI parser\Vrekrer_scpi_parser.cpp.o] Error 1 ============================================================================================================================================= [FAILED] Took 1.07 seconds

Paul202003 commented 3 years ago

Hi Vrekrer,

This is a great project!

Actually I came across the following using the nice SCPI_Dimmer example. If I change SCPI_MAX_COMMANDS (for example from 20 to 24) the SCPI-parser freezes.

define SCPI_MAX_COMMANDS 24

include "Vrekrer_scpi_parser.h"

Where is SCPI_MAX_COMMANDS monitored in the "Vrekrer_scpi_parser.cpp" file? I use Arduino IDE 1.8.13 and Arduino MEGA board.

Please let me know. With kind regards, Paul.

Vrekrer commented 3 years ago

Hello Looks like that is not possible to override define statements used by libraries. (using the Arduino IDE)

https://arduino.stackexchange.com/questions/20439/override-define-statements-in-libraries https://www.reddit.com/r/arduino/comments/9dj3ql/overridingremoving_defines_from_a_lib/

you will need to modify the library header file.

I will try to find a workaround.

franciszekjuras commented 3 years ago

Arduino pulse generator is a project of mine that uses your great library. Regarding define statement override problem, I solved it by simply coping source file contents into header (you can copy it from my project to save some hassle). I added v2 to the filename to avoid name collision with installed library.

hb020 commented 1 year ago

Like franciszekjuras, I changed the library to one header file, so I could change the relevant #define's. Also modified the library:

See my project batterymeter. Code is in the batterymeter directory (stupid Arduino IDE...)

palmerr23 commented 1 year ago

Silicon Chip Magazine project "Swiss Army Knife" https://www.siliconchip.com.au/Issue/2023/April/Automated+Test+Bench