Git Product home page Git Product logo

simplerpc's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

simplerpc's Issues

int vec_test3(Vector<uint8_t> &v, int flags) --> CRASH

Calling the following function via RPC results in a crash (corrupt heap detected) when the function returns.

int vec_test3(Vector<uint8_t> &v, int flags)
{
    return flags+1;
}

Without an int after the Vector, there is no issue.

Vector<uint8_t> vec_test1(Vector<uint8_t> &v)
{
    Vector<uint8_t> res = Vector<uint8_t>(v.size);
    for (int i=0;  i<v.size;  i++)
        res[v.size-i-1] = v[i];
    return res; 
}

Vector<uint8_t> vec_test2(int sz)
{
    auto res = Vector<uint8_t>(sz);
    for (int i=0;  i<sz;  i++) res[i] = 'A' + i;
    return res;
}

simple_rpc: error: invalid protocol header

Hello,
thanks for this awesome library!
I get this error when using simple_rpc:

$ simple_rpc call /dev/ttyUSB0 foo 1
usage: simple_rpc [-h] [-v] {list,call} ...
simple_rpc: error: invalid protocol header

I suspect it's because I use it with another library that outputs a lot of traces on Serial port.
If I comment out that other library, it works fine.
Any idea how to manage that? I could go and remove the traces in the other library, but it's heavy and not really under my control...

Thanks

Crash after processing any command on ESP32

I've used simpleRPC successfully on an Arduino and a Teensy 4. I'm now trying it on an ESP32 (Adafruit Huzzah32 feather) and running into a crash. Specifically, the board resets after completing any RPC call, including requesting a command list.

Here's a minimal reproduction:

#include <simpleRPC.h>

void setup() {
  Serial.begin(115200);
}

void loop() {
  interface(Serial, millis, "uptime: returns uptime in milliseconds");
}

If I reset the board, wait 5 seconds, and then call
simple_rpc call -b 115200 COM6 I get a response like 7427. If I issue the command back-to-back, I get responses like 2450, 2427, 2475 indicating a reset has taken place. (Probably flashing an LED on reset would be a more obvious way of indicating the reset, now that I think about it.)

Software Versions:
simpleRPC 3.2.0
Arduino IDE 2.2.1
esp32 BSP (Espressif's) 2.0.11

Pack not existing

the method pack does not exist anymore. It was removed in 4710992

and exchanged with makeTuple.

work ok its just not up to date in the docs.
Or rather the description of how to use methods of objects was not updated.

usb_serial_class plugin support

Is your feature request related to a problem? Please describe.
I want to use simpleRPC with a Teensy 3.6. I tried to run HardwareSerialIO::begin with the Serial object but the compiler tells me error: no matching function for call to 'HardwareSerialIO::begin(usb_serial_class&)

Describe the solution you'd like
I think a new plugin that works with usb_serial_class, or possibly overloading HardwareSerialIO::begin to work with it.

Alternative solution
They both inherit from Stream so maybe just have HardwareSerialIO::begin take in a Stream? This might cause other issues if used improperly though, I don't know what else a Stream might be.

Additional context
I figured out that this is because the Teensy treats the USB serial port separately from the I/O pin serial ports, unlike most ordinary Arduinos which link the USB TX and RX with the serial TX and RX via a resistor and thus HardwareSerial covers both. So with the Teensy they are treated with a separate class, but are still hardware serial ports (at least for the Teensy 3.6, I haven't looked at other ones yet).

I am pretty new to the Teensy/Arduino world, not to mention C++, but this seems like an easy problem that only needs a few lines of code to fix. I will give it the old college try tomorrow.

Allow class functions

It would make things a bit more convenient if it were possible to use class functions with the template system:

Adafruit_BME280 bme;

void setup(void)
{
  Serial.begin(9600);
  bme.begin();
}

void loop(void)
{
  interface(
    Serial,
    bme.readTemperature, F("get_temperature: @return: Temperature [C]"));
}

I'm not sure how difficult / if it is worth doing this with the current template system? It is not too much trouble to just wrap these in another function.

Heap corruption with Vector's as function arguments

I'm getting heap corruption when passing Vector arguments to functions called by simpleRPC.

Setting Vector.destroy = false in function void _read(Vector *data) in read.tcc appears to fix the problem, although this may (will?) result in a memory leak.

Test code (snippet):

Vector<uint8_t> send_Vector(Vector<uint8_t> data) {
    ESP_LOGD("esp_connect", "send_Vector %d", data.size);
    return data[1];
}

interface(send_Vector, F("send_Vector"));

multiple calls to function returning Vector crashes on the 3rd Call

Hello,

First thank you for the library and please excuse me but the behavior is driving me nuts and I don't know how to debug it by myself. I am trying to get data back from a color sensor on arduino through simpleRPC.

here is the declaration of the functions:

bool as7341setLed(bool enable_led, uint16_t led_current_ma) {
  as7341.setLEDCurrent(led_current_ma);
  as7341.enableLED(enable_led);
  return enable_led;
}

Vector<uint16_t> as7341read(){
  if (!as7341.readAllChannels(readings))
  {
![OK](https://user-images.githubusercontent.com/5367483/214178461-f3574d95-5b6d-468a-810b-b003f1bdd2ea.png)

    //Serial.println("Error reading all channels!");
    for (int i=0;i<12;++i){readings[i]=0;};
  }else{
    for (int i=0;i<12;++i){u2[i]=readings[i];};
  }
  return u2;
}

here is my interface definition:

  interface(
  Serial,
  as7341setLed, "as7341setLed: Set LED brightness. @enable_led: enable_led. @led_current_ma: led_current_ma. @return: enable_led.",
  as7341read, "as7341read: Read all color sensors. @return: readings.");

I am using the Python interface.
What I observe is that the setLed works everytime and returns reliably everytime
For the read function it reads correctly 2 whole vector of 12 ints... but on the 3rd call the python seems to hang before returning the array.
if I press the reset button on the arduino it traces back io.py in the _read_basic() function
with unpack requires a buffer of 4 bytes.

I added some logging info but it doesn't help me much understand the issue.
Here is a screen capture representing the first two calls
OK
and here is the 3rd one:
NotOK

and here is the Log:

1:04:18 AM
<   H   B
<   H   B
<   H   B
1:04:20 AM
<   I   ?
1:04:20 AM
False
1:04:23 AM
<   I   ['H']
1:04:24 AM
<   I   H
<   I   H
<   I   H
<   I   H
<   I   H
<   I   H
<   I   H
<   I   H
<   I   H
<   I   H
<   I   H
1:04:24 AM
[95, 199, 309, 537, 2437, 206, 967, 1653, 1905, 1138, 2436]
1:04:29 AM
<   I   ['H']
<   I   H
<   I   H
<   I   H
<   I   H
<   I   H
<   I   H
<   I   H
<   I   H
<   I   H
<   I   H
<   I   H
1:04:29 AM
[95, 198, 309, 537, 2434, 206, 969, 1655, 1906, 1140, 2441]
1:04:37 AM
<   I   ['H']
1:04:43 AM
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_28600\2026148949.py in <module>
----> 1 my_list=interface.as7341read()
      2 my_list

<string> in as7341read(self)

~\AppData\Roaming\Python\Python39\site-packages\simple_rpc\simple_rpc.py in call_method(self, name, *args)
    186         # Read return value (if any).
    187         if method['return']['fmt']:
--> 188             return self._read(method['return']['fmt'])
    189         return None
    190 

~\AppData\Roaming\Python\Python39\site-packages\simple_rpc\simple_rpc.py in _read(self, obj_type)
    101         :returns: Return value.
    102         """
--> 103         return read(
    104             self._connection, self.device['endianness'], self.device['size_t'],
    105             obj_type)

~\AppData\Roaming\Python\Python39\site-packages\simple_rpc\io.py in read(stream, endianness, size_t, obj_type)
     83     logging.info(endianness,' ',size_t,' ',obj_type)
     84     if isinstance(obj_type, list):
---> 85         length = _read_basic(stream, endianness, size_t)
     86         logging.info('it is a list')
     87         return [

~\AppData\Roaming\Python\Python39\site-packages\simple_rpc\io.py in _read_basic(stream, endianness, basic_type)
     29     full_type = (endianness + basic_type).encode('utf-8')
     30     logging.info('read full_type: ',full_type)
---> 31     return unpack(full_type, stream.read(calcsize(full_type)))[0]
     32 
     33 

error: unpack requires a buffer of 4 bytes

I tried to change the array to a size of one only ... I tried to change the type by casting it to int.
Nothing seems to allow me to retrieve more than 2 arrays from the sensor...
Thank you for your help.

stack size

I getting weird crashes (memory corruption) that appear to be related to the number of functions passed to interface(...).

I suspect (but am not at all sure this is correct) it's is because of running out of stack. Doesn't place interface(...) a lot of data on the stack (and copies there in each call)?

Would it be possible to instead allocate the arguments to interface(...) on the heap or as statics?

Enable a timeout after opening a serial connection

Is your feature request related to a problem? Please describe.

Depending on the connection speed and/or hardware of the serial port the opening of the interface may fail and you have to CTRL-C'it ...

Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from simple_rpc import Interface
>>> interface = Interface('/dev/ttyUSB0',9600)
^CTraceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/xxx/Downloads/simpleRPC/simple_rpc/simple_rpc.py", line 133, in __init__

Describe the solution you'd like

Enable another parameter to increase the timeout to prevent a conflict with the bootloader of the Arduino. Probably like this in file simple_rpc/simple_rpc.py:

class Interface(object):
    def __init__(self, device, baudrate=9600, towait=1):
        """Initialise the class.

        :arg str device: Serial device name.
        :arg int baudrate: Baud rate.
        :arg int towait: Wait after opening serial interface.
        """
        try:
            self._connection = Serial(device, baudrate)
        except SerialException as error:
            raise IOError(error.strerror.split(':')[0])
        sleep(towait)

Thanks.

Void methods: Wait for response?

Is your feature request related to a problem? Please describe.
I've just noticed that calling void methods / methods without a return value does not block, they seem to return immediately. This caused errors, as I was expecting that the arduino method was done when the method returned.

Describe the solution you'd like
It would be nice to document that void method dont block. Alternatively, void methods could block, to behave similar to all other functions (this would be a breaking change).

Java client for Android

Is there by any chance Java implementation of the client similar to python? The goal is to communicate with Android smartphone.

Error HardwareSerial Arduino

Describe the bug
At the time of compiling the HardwareSerial.ino test project does not compile with the following errors:

In file included from C:\Users\User\Documents\Arduino\libraries\simpleRPC\src/rpcCall.tcc:5:0,

             from C:\Users\User\Documents\Arduino\libraries\simpleRPC\src/interface.tcc:13,

             from C:\Users\User\Documents\Arduino\libraries\simpleRPC\src/simpleRPC.h:5,

             from C:\Users\User\Documents\Arduino\PRUEBARPC\PRUEBARPC.ino:1:

C:\Users\User\Documents\Arduino\libraries\simpleRPC\src/read.tcc: In instantiation of 'void rpcRead(I&, T*) [with I = HardwareSerial; T = unsigned char]':

C:\Users\User\Documents\Arduino\libraries\simpleRPC\src/interface.tcc:113:12: required from 'void interface(I&, Args ...) [with I = HardwareSerial; Args = {unsigned char ()(unsigned char), const __FlashStringHelper}]'

C:\Users\User\Documents\Arduino\PRUEBARPC\PRUEBARPC.ino:18:73: required from here

C:\Users\User\Documents\Arduino\libraries\simpleRPC\src/read.tcc:19:3: error: no matching function for call to 'HardwareSerial::read(byte*, unsigned int)'

io.read((byte*)data, sizeof(T));

^

In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:232:0,

             from sketch\PRUEBARPC.ino.cpp:1:

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:126:17: note: candidate: virtual int HardwareSerial::read()

 virtual int read(void);

             ^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:126:17: note: candidate expects 0 arguments, 2 provided

exit status 1
Error compilando para la tarjeta Arduino/Genuino Uno.

Exception/error reporting

Hello,
if the function called via RPC throws an exception, what will happen?
In general, how do you advice to report errors in simpleRPC?

Support for SAMD architecture

I'm using a feather M0 and would like to use this library for SAMD architecture but when I try to compile it's saying the library is only for AVR micro-controllers.

I'm imagining a SerialIO class would replace HardwareSerialIO and SoftwareSerialIO, like this:

#ifndef SIMPLE_RPC_SERIAL_IO_H_
#define SIMPLE_RPC_SERIAL_IO_H_

#include <Arduino.h>

class SerialIO {
  public:
    SerialIO(void) {}
    void begin(Stream&);
    size_t available(void);
    size_t read(byte*, size_t);
    size_t write(byte*, size_t);
  private:
    Stream* _ss;
};

typedef SerialIO HardwareSerialIO;  // for backwards compatibility
typedef SerialIO SoftwareSerialIO;  // for backwards compatibility

#endif

RS485 Support

Make it easy to allow RS485 half duplex communications.

Describe the solution you'd like
Add an I/O plugin to support RS485 half duplex, this has additional timing requirements over the normal serial communications (which are non-blocking).

Compiling Error with CONTROLLINO MEGA

Describe the bug
We are using simpleRPC on a Controllino MEGA which has worked great so far. Since we updated your library from 2.0.1 to 3.0.0, we receive an compiling error.

To Reproduce
We run this code on our Controllino:

 #include <Controllino.h>   Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch.
#include <simpleRPC.h>
    
    int i=0;
    const int lowestInputPin = 0;
    const int highestInputPin = 15;
    const int lowestOutputPin = 0;
    const int highestOutputPin = 16;
    int CONTROLLINO_D = 0;
    int CONTROLLINO_A = 0;
    byte pump_speed[11];
    byte flow_raw[11];
byte get_byte_element(byte index) {
  return flow_raw[index];
}
bool set_byte_element(byte index, byte value) {
  pump_speed[index] = value;
  return true;
}
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);//

  // set Inputpins 0 - 15 as analog Inputs:
  for (int thisInputPin = lowestInputPin; thisInputPin <= highestInputPin; thisInputPin++) {
    pinMode(CONTROLLINO_A+thisInputPin, INPUT);
    }
  // set Outputpins 0 - 16 as digital outputs:
  for (int thisOutputPin = lowestOutputPin; thisOutputPin <= highestOutputPin; thisOutputPin++) {
    pinMode(CONTROLLINO_D+thisOutputPin, OUTPUT);
    }
  int  PumpspeedAblauf = 200;
  int  PumpspeedFilter = 150;
  analogWrite(CONTROLLINO_D11, PumpspeedAblauf);                        // abpumpen
  analogWrite(CONTROLLINO_D16, PumpspeedFilter);                        // Filtern
}
void loop() {
  interface(
  digitalRead,
    "digital_read: Read digital pin. @pin: Pin number. @return: Pin value.",
  digitalWrite,
    "digital_write: Write to a digital pin. @pin: Pin number. @value: Pin value.",
  analogRead,
    "analog_read: Read analog pin. @pin: Pin number. @return: Analog value.",
  analogWrite,
    "analog_write: Write to an analog pin (takes 1.2s to proceed). @pin: Pin number. @value: Analog value.",
  get_byte_element,
    "get_byte_element: Reads a byte element from array. @index: index of element. @return: element.",
  set_byte_element,
    "set_byte_element: Writes a byte element into an array. @index: index of element. @value: value of element. @return: acknowledgement.");

  for (i=0; i<=10; i++){
    analogWrite(CONTROLLINO_D0+i, pump_speed[i]);
    flow_raw[i] = analogRead(CONTROLLINO_A0+i);
  }
}

refer to this for the library setup. As we compile this error code occurs:

Arduino: 1.8.13 (Windows 10), Board: "CONTROLLINO MEGA"


In file included from C:\Program Files (x86)\Arduino\libraries\simpleRPC\src/simpleRPC.h:5:0,

                 from ...\arduino\port_extender\port_extender_Pressure\port_extender_Pressure.ino:2:

C:\Program Files (x86)\Arduino\libraries\simpleRPC\src/interface.tcc: In instantiation of void interface(I&, Args ...) [with I = int(unsigned char); Args = {const char*, void (*)(unsigned char, unsigned char), const char*, int (*)(unsigned char), const char*, void (*)(unsigned char, int), const char*, unsigned char (*)(unsigned char), const char*, bool (*)(unsigned char, unsigned char), const char*}]:

...\arduino\port_extender\port_extender_Pressure\port_extender_Pressure.ino:63:139:   required from here

C:\Program Files (x86)\Arduino\libraries\simpleRPC\src/interface.tcc:110:10: error: request for member available in io, which is of non-class type int(unsigned char)

   if (io.available()) {

       ~~~^~~~~~~~~

exit status 1

Error compiling for board CONTROLLINO MEGA.

Expected behavior
The error code stated above appears. As we switch back to version 2.0.1 the IDE compiles without any error and all works fine.

Desktop (please complete the following information):

  • OS: Windows 10
  • Arduino: 1.8.13

Question: Sending a request to RCP server and reading response.

We are evaluating the use of SimpleRPC in Sming and for export functions and writing the server part this library is really great for us.

My question is how to implement also the client side in C/C++ using this library? For example we would like to have a function like this one:

uint8_t digitalRead(uint16_t pin)
{
	// TODO: send the "digitalRead" command with one parameter the pin
       // hostedClient.send("digitalRead", pin);
       
        // TODO: wait for response....
        // uint8_t result = hostedClient.wait(sizeof(uint8_t));
    
        return result;
}

The hostedClient after a successful connection will get the list of available functions. After that the send command will use the provided name as first argument to find the id of the command. And use the rest of the arguments to pass them directly to a client RPC function. Finally the hostedClient.wait will wait until the desired number of bytes are sent back.

Can we use rcpCall or rpcWrite somehow for sending the request to the RPC server?

Graceful disconnection & const char to PROGMEM

Hi Jeroen:

Is your feature request related to a problem? Please describe.

  • Python:It would be nice to terminate a connection between python program and Arduino gracefully to change serial connection parameter without stopping the python program
  • Arduino: Please check if the const char[] of the interface() definition can be moved to the flash memory (PROGRAM) iso SRAM (DATA). At the moment I'm running low while defining a number of interface() routines, e.g.
DATA:    [=======   ]  70.7% (used 1448 bytes from 2048 bytes)
PROGRAM: [===       ]  30.8% (used 9472 bytes from 30720 bytes)

Describe the solution you'd like

  • Python: something like:
interface = Interface('/dev/ttyACM0')
interface.connect()
interface.terminte()
  • Arduino:
    Using F() macro and PROGMEM

Thanks,
Andy

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.