Closed Vanguard4893 closed 2 years ago
Hello
You might want to set up your instrument's WiFi connection as a socket server (SCPI instruments uses port 5025
).
Then read the messages sent to the socket into a *char
variable and process that using the Execute
function.
Use a dummy Stream
interface (like Serial
) as the second parameter in the Execute
call. (I will try to simplify this in a next release)
If you have instrument output, write it back into the socket.
Ethernet_Instrument
example does exactly that, but for the ENC28J60 Ethernet hardware.
On your controller/computer side, just connect to the socket and read/write it.
Most VISA libraries does this for you if you use the 'TCPIP0::<your ip>::5025::SOCKET'
string as the instrument identifier.
I'm using WiFiServer (Identifier "SCPIClient") to open the port 5025, no problem, and can receive data on this port, and print back to it. I've put this together for processing the input, however the ESP32 crashes when called:
if(SCPIClient.connected()){
char line_buffer[256];
unsigned char read_length;
read_length = SCPIClient.readBytesUntil('\n', line_buffer, 256);
if(read_length > 0)
{
#ifdef SCPIDEBUG
Serial.print("SCPI Message Buffer: ");
Serial.println(line_buffer);
#endif
my_instrument.Execute(line_buffer, Serial);
}
}
Removing the my_instrumment.Execute line stops the crash, and the Serial debug prints out the proper *IDN? when sent, so I'm close to having it work by the look.
Cheers
I have never used or tested WiFi hardware/libraries, but I believe that WiFiServer already creates a Stream
interface.
In that case, it is easier to use the ProcessInput(Stream &interface, const char* term_chars)
function. All the examples uses that with Serial
as Stream
interface
I think that your code will be my_instrument.ProcessInput(SCPIClient, "\n")
Take a look at this for an example using the Ethernet library that, as the web page says, should be very similar to the WiFi library.
Your code did not work because it has two problems:
Execute
function must be a *char
and not a char[]
*char
you pass to Execute
must include the message termination chars at the end ('\n'
for your)I should also point out, in my use case, sending the data in via the debug serial port with:
my_instrument.ProcessInput(Serial, "\n");
also results in the microcontroller crashing :
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x4000c547 PS : 0x00060630 A0 : 0x800e8d25 A1 : 0x3ffb1d50
A2 : 0x00000000 A3 : 0x0000003b A4 : 0x3ffb81cc A5 : 0x3ffb80c0
A6 : 0x00000000 A7 : 0x00000000 A8 : 0x801090ec A9 : 0x3ffb1d30
A10 : 0x00000000 A11 : 0x3f41706c A12 : 0x3ffb81cc A13 : 0x00000001
A14 : 0x3ffb89c9 A15 : 0x3ffb0060 SAR : 0x0000000a EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xffffffff
ELF file SHA256: 0000000000000000
Backtrace: 0x4000c547:0x3ffb1d50 0x400e8d22:0x3ffb1d70 0x400e8fe6:0x3ffb1d90 0x400e910b:0x3ffb1e40 0x400d34de:0x3ffb1e60 0x400ed441:0x3ffb1fb0 0x4008a30e:0x3ffb1fd0
Rebooting...
Hi Vrekrer, Thanks for your assistance so far.
I have tried the simple line:
my_instrument.ProcessInput(SCPIClient, "\n")
However I get the same crash & core dump:
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x4000c547 PS : 0x00060e30 A0 : 0x800e8c81 A1 : 0x3ffb1e30
A2 : 0x00000000 A3 : 0x0000003b A4 : 0x3ffb8a5c A5 : 0x3ffb80c0
A6 : 0x00000000 A7 : 0x00000000 A8 : 0x801090b4 A9 : 0x3ffb1e10
A10 : 0x00000000 A11 : 0x3f41704c A12 : 0x3ffb8a5c A13 : 0x00000001
A14 : 0x00000005 A15 : 0x00000000 SAR : 0x0000000a EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xffffffff
ELF file SHA256: 0000000000000000
Backtrace: 0x4000c547:0x3ffb1e30 0x400e8c7e:0x3ffb1e50 0x400e8fae:0x3ffb1e70 0x400e90d3:0x3ffb1f20 0x400d3512:0x3ffb1f40 0x400ed409:0x3ffb1fb0 0x4008a30e:0x3ffb1fd0
Rebooting...
I have also tried paring everything back to bare bones, with just a serial connection, and only an IDN command as per your example:
/*
Vrekrer_scpi_parser library.
SCPI Dimmer example.
Demonstrates the control of the brightness of a LED using SCPI commands.
Hardware required:
A LED attached to digital pin 9
or a resistor from pin 9 to pin 13 to use the built-in LED
Commands:
*IDN?
Gets the instrument's identification string
SYSTem:LED:BRIGhtness <value>
Sets the LED's brightness to <value>
Valid values : 0 (OFF) to 10 (Full brightness)
SYSTem:LED:BRIGhtness?
Queries the current LED's brightness value
SYSTem:LED:BRIGhtness:INCrease
Increases the LED's brightness value by one
SYSTem:LED:BRIGhtness:DECrease
Decreases the LED's brightness value by one
*/
#include "Arduino.h"
#include "Vrekrer_scpi_parser.h"
SCPI_Parser my_instrument;
void Identify(SCPI_C commands, SCPI_P parameters, Stream& interface){
interface.println(F("Vrekrer,Arduino SCPI Dimmer,#00,v0.4"));
}
void setup()
{
my_instrument.RegisterCommand("*IDN?", &Identify);
my_instrument.SetCommandTreeBase(F("SYSTem:LED"));
Serial.begin(9600);
}
void loop(){
my_instrument.ProcessInput(Serial, "\n");
}
This much simplified example also gives a core dump. Could this be something related to the ESP32 itself?
Sorry. I never used an ESP32. I will try to get one and test it.
Hi @Vanguard4893 , I built and uploaded Your simplified sketch into ESP32 Dev Module and it works fine for me.
Hi Bogus43,
How odd. I've read things on forums about ESP32 modules not all operating the same before, with the same code. Maybe I've got an odd one. Now I'm totally confused as to what's going on!
I'll try a full flash erase & give it another crack I think.
Cheers
Seems that I just can't get it going on this particular ESP32 - I do have some other bare modules which are awaiting PCBs so I'll have to try with one of those.
I will report back if I get anywhere with it.
If you could share the code from the wifi (minimal code to reproduce the problem) then I can see if this would work on my ESP32. Maybe it's not a code problem, but a hardware.
Hi Bogus43,
The code below should be a minimal implementation of what I'm doing. This compiles fine in Platformio. I get the same crash & core dump though. I have another ESP32 DevKit on order, so I'll try it on another one. I also think this is a hardware issue at this point.
#include <ESPAsyncWebServer.h>
#include <ESPAsyncWiFiManager.h>
#include <Vrekrer_scpi_parser.h>
AsyncWebServer server(80);
WiFiServer SCPI_Server(5025);
WiFiClient SCPIClient;
DNSServer dns;
SCPI_Parser my_instrument; //SCPI Object
bool fromSerial = true;
long oldTime = 0;
void PrintToInterface(char *print_str)
{
SCPIClient.println(print_str);
}
/* SCPI FUNCTIONS */
void Identify(SCPI_C commands, SCPI_P parameters, Stream &interface)
{
char IDN[] = "Instrument Identifier, v1.0";
PrintToInterface(IDN);
}
void CheckForConnections()
{
if (SCPI_Server.hasClient())
{
// If we are already connected to another computer,
// then reject the new connection. Otherwise accept
// the connection.
if (SCPIClient.connected())
{
Serial.println(F("SCPI Connection rejected"));
SCPIClient.stop();
}
else
{
Serial.println(F("SCPI Connection accepted"));
SCPIClient = SCPI_Server.available();
}
}
}
void setup(void)
{
Serial.begin(9600); //Init Serial Link
while (!Serial)
;
my_instrument.RegisterCommand("*IDN?", &Identify);
AsyncWiFiManager wifiManager(&server, &dns);
wifiManager.autoConnect("ESP32");
wifiManager.setConfigPortalTimeout(180);
SCPI_Server.begin(); //Begin SCPI Server
}
void loop(void)
{
if (millis() - oldTime > 500)
{
CheckForConnections();
}
fromSerial = true;
my_instrument.ProcessInput(Serial, "\n");
if (SCPIClient.connected())
{
fromSerial = false;
my_instrument.ProcessInput(SCPIClient, "\n");
}
}
Hi guys,
I've now tried the same code on 3 different ESP32 microcontrollers (two devkits & a bare module), and I get the exact same CPU crash & reboot on all of them. Definitely lost as to what to do now!
Cheers
Maybe try upload code from Arduino IDE and check that You selected proper board version. I changed 1 library [ESPAsyncWiFiManager], see link: https://www.arduino.cc/reference/en/libraries/espasync_wifimanager/
Hi Bogus43,
I've tried in the Arduino IDE, and while the code compiles, I get the same crash when I feed the micro an *IDN? command over network.
My board settings all appear to be correct, however I'm open to any suggestions. (ESP32 Dev Module, 240MHz Core Clock, DIO, 80MHz, SPI Flash)
Cheers
Hello.
I created this example WiFi_ESP32.ino that works on Serial and WiFi.
My setup is:
Hardware:
Software:
Hi Vrekrer,
Thanks for the example code. I've cracked the problem! I still couldn't get it to work, then realised I wasn't using the git version of the library - the one that's in the Arduino library manager & Platformio's library manager is an older version, and causes the crash. With the library manager version replaced with a clone from git, all works correctly.
Thanks!
Thanks for the feedback.
As soon as I get some time, I will make a new release.
Some remarks about using this library in an ESP32 (or any other system with "a lot" of RAM)
#define SCPI_*
values at Vrekrer_scpi_parser.h
. Any increase in that values will increase the RAM usage.CommandTree_Check.ino
example) change SCPI_HASH_TYPE
to uint16_t
or uint32_t
Hi Vrekrer,
Thanks for the hints with the defines, I did indeed have to make some edits to prevent hash collisions in my command tree.
I do believe this is solved now, so I'll close off this issue. Using the git version of the library fixed all the issues I have encountered.
Cheers
I'm building an instrument based around the ESP32, and was wondering if I could get an example or hints on how to get this library operating correctly with the WiFi interface on that microcontroller?
I'm not much of a developer, and am rather stuck!
Cheers