GithubHelp home page GithubHelp logo

pycmdmessenger's Introduction

#PyCmdMessenger

Python class for communication with an arduino using the CmdMessenger serial communication library. It sends and recieves messages, automatically converting python data types to arduino types and vice versa.

This project is not affiliated with the CmdMessenger project, though it obviously builds off of their excellent work.

Installation:

  • From github:
    • git clone https://github.com/harmsm/PyCmdMessenger.git
    • cd PyCmdMessenger
    • sudo python3 setup.py install
  • From PyPI:
    • sudo pip3 install PyCmdMessenger

To test the library:

  • Clone the source from git
  • Compile the arduino sketch in the pingpong_arduino directory
  • Transfer the compiled sketch to an arduino plugged into the computer
  • Run the test/pingpong_test.py script. This will pass a variety of data types between the local computer and the arduino.

Compatibility

  • Compatibility: Python 3.x (a tweaked version supporting Python 2.7 is here).
  • Should work on all platforms supported by pyserial.
  • Known to work on Raspberry Pi (raspbian), linux (Ubuntu 15.10), and Windows 10.

Dependencies

pyserial should be installed automatically by pip or the installaion script. For CmdMessenger, please follow the directions on their site. Copies of the CmdMessenter 4.0 main .cpp and .h files are included in the PyCmdMessenger repo in the test/arduino and examples/arduino directories.

##Example code

A typical CmdMessenger message has the following structure:

Cmd Id, param 1, [...] , param N;

The PyCmdMessenger class constructs/parses these strings, as well as sending them over the serial connection via pyserial.

To ensure stable communication with PyCmdMessenger:

  • PyCmdMessenger instances must be given a list of command names in the same order as those commands are specified in the arduino sketch.
  • PyCmdMessenger instances should be given a list of the data types for each command in the same order as those commands are specified in the arduino sketch.
  • Separators must match between the PyCmdMessenger instance and the arduino sketch.
    • field separator (default ",")
    • command separator (default ";")
    • escape separator, so field and command separators can be sent within strings (default "/")
  • Baud rate must match between PyCmdMessenger class and arduino sketch.

A basic example is shown below. These files are in the examples directory.

###Arduino

/* -----------------------------------------------------------------------------
 * Example .ino file for arduino, compiled with CmdMessenger.h and
 * CmdMessenger.cpp in the sketch directory. 
 *----------------------------------------------------------------------------*/

#include "CmdMessenger.h"

/* Define available CmdMessenger commands */
enum {
    who_are_you,
    my_name_is,
    sum_two_ints,
    sum_is,
    error,
};

/* Initialize CmdMessenger -- this should match PyCmdMessenger instance */
const int BAUD_RATE = 9600;
CmdMessenger c = CmdMessenger(Serial,',',';','/');

/* Create callback functions to deal with incoming messages */

/* callback */
void on_who_are_you(void){
    c.sendCmd(my_name_is,"Bob");
}

/* callback */
void on_sum_two_ints(void){
   
    /* Grab two integers */
    int value1 = c.readBinArg<int>();
    int value2 = c.readBinArg<int>();

    /* Send result back */ 
    c.sendBinCmd(sum_is,value1 + value2);

}

/* callback */
void on_unknown_command(void){
    c.sendCmd(error,"Command without callback.");
}

/* Attach callbacks for CmdMessenger commands */
void attach_callbacks(void) { 
  
    c.attach(who_are_you,on_who_are_you);
    c.attach(sum_two_ints,on_sum_two_ints);
    c.attach(on_unknown_command);
}

void setup() {
    Serial.begin(BAUD_RATE);
    attach_callbacks();    
}

void loop() {
    c.feedinSerialData();
}

Python

# ------------------------------------------------------------------------------
# Python program using the library to interface with the arduino sketch above.
# ------------------------------------------------------------------------------

import PyCmdMessenger

# Initialize an ArduinoBoard instance.  This is where you specify baud rate and
# serial timeout.  If you are using a non ATmega328 board, you might also need
# to set the data sizes (bytes for integers, longs, floats, and doubles).  
arduino = PyCmdMessenger.ArduinoBoard("/dev/ttyACM0",baud_rate=9600)

# List of command names (and formats for their associated arguments). These must
# be in the same order as in the sketch.
commands = [["who_are_you",""],
            ["my_name_is","s"],
            ["sum_two_ints","ii"],
            ["sum_is","i"],
            ["error","s"]]

# Initialize the messenger
c = PyCmdMessenger.CmdMessenger(arduino,commands)

# Send
c.send("who_are_you")
# Receive. Should give ["my_name_is",["Bob"],TIME_RECIEVED]
msg = c.receive()
print(msg)

# Send with multiple parameters
c.send("sum_two_ints",4,1)
msg = c.receive()

# should give ["sum_is",[5],TIME_RECEIVED]
print(msg)

##Format arguments

The format for each argument sent with a command (or received with a command) is determined by the command_formats list passed to the CmdMessenger class (see example above). Alternatively, it can be specified by the keyword arg_formats passed directly to the send or receive methods. The format specification is in the table below. If a given command returns a single float value, the format string for that command would be "f". If it returns five floats, the format string would be "fffff". The types can be mixed and matched at will. "si??f" would specify a command that sends or receives five arguments that are a string, integer, bool, bool, and float. If no argument is associated with a command, an empty string ("") or None can be used for the format.

###Format reference table

format arduino type Python Type Arduino receive Arduino send
"i" int int int value = c.readBinArg<int>(); c.sendBinCmd(COMMAND_NAME,value);
"b" byte int int value = c.readBinArg<byte>(); c.sendBinCmd(COMMAND_NAME,value);
"I" unsigned int int unsigned int value = c.readBinArg<unsigned int>(); c.sendBinCmd(COMMAND_NAME,value);
"l" long int long value = c.readBinArg<long>(); c.sendBinCmd(COMMAND_NAME,value);
"L" unsigned long int unsigned long value = c.readBinArg<unsigned long>(); c.sendBinCmd(COMMAND_NAME,value);
"f" float float float value = c.readBinArg<float>(); c.sendBinCmd(COMMAND_NAME,value);
"d" double float double value = c.readBinArg<double>(); c.sendBinCmd(COMMAND_NAME,value);
"?" bool bool bool value = c.readBinArg<bool>(); c.sendBinCmd(COMMAND_NAME,value);
"c" char str or bytes, length = 1 char value = c.readBinArg<char>(); c.sendBinCmd(COMMAND_NAME,value);
"s" char[] str or bytes char value[SIZE] = c.readStringArg(); c.sendCmd(COMMAND_NAME,value);

PyCmdMessenger takes care of type conversion before anything is sent over the serial connection. For example, if the user sends an integer as an "f" (float), PyCmdMessenger will run float(value) in python before passing it. It will warn the user for destructive conversions (say, a float to an integer). It will throw a ValueError if the conversion cannot be done (e.g. the string 'ABC' to integer). It will throw an OverflowError if the passed value cannot be accomodated in the specififed arduino data type (say, by passing an integer greater than 32767 to a 2-byte integer, or a negative number to an unsigned int). The sizes for each arduino type are determined by the XXX_bytes attributes of the ArduinoBoard class.

With the exception of strings, all data are passed in binary format. This both minimizes the number of bits sent and makes sure the sent values are accurate. (While you can technically send a float as a string to the arduino, then convert it to a float via atof, this is extremely unreliable.)

PyCmdMessenger will also automatically escape separators in strings, both on sending and receiving. For example, the default field separator is , an dthe default escape character is /. If the user sends the string Hello, my name is Bob., PyCmdMessenger will convert this to Hello/, my name is Bob. CmdMessenger on the arduino will strip out the escape character when received. The same behavior should hold for recieving from the arduino.

###Special formats

  • "*" tells the CmdMessenger class to repeat the previous format for all remaining arguments, however many there are. This is useful if your arduino function sends back an undetermined number of arguments of the same type, for example. There are a few rules for use:

    • Only one * may be specified per format string.
    • The one * must occur last
    • It must be preceded by a different format that will then be repeated.

    Examples:

    • "i*" will use an integer format until it runs out of fields.
    • "fs?*" will read/send the first two fields as a float and string, then any remaining fields as bool.

##Testing

The test directory has an arduino sketch (in pingpong_arduino) that can be compiled and loaded onto an arudino, as well as a python test script, pingpong_test.py. This will send a wide range of values for every data type back and forth to the arduino, reporting success and failure.

##Known Issues

  • Opening the serial connection from a linux machine will cause the arduino to reset. This is a known issue with pyserial and the arudino architecture. This behavior can be prevented on a windows host using by setting arduino.ArduinoBoard(enable_dtr=False) (the default). See issue #9 for discussion.

##Quick reference for CmdMessenger on arduino side For more details, see the CmdMessenger project page.

###Receiving

/* c is an instance of CmdMessenger (see example sketch above) */
/* ------- For all types except strings (replace TYPE appropriately) --------*/
int value = c.readBinArg<TYPE>();

/* ----- For strings (replace BUFFER_SIZE with maximum string length) ------ */
char string[BUFFER_SIZE] = c.readStringArg();

###Sending

/* COMMAND_NAME must be enumerated at the top of the sketch.  c is an instance
 * of CmdMessenger (see example sketch above) */

/* ------------------- For all types except strings ------------------------*/

// Send single value
c.sendBinCmd(COMMAND_NAME,value);

// Send multiple values via a single command
c.sendCmdStart(COMMAND_NAME);
c.sendCmdBinArg(value1);
c.sendCmdBinArg(value2);
// ...
// ...
c.sendCmdEnd();

/* ------------------------- For strings ------------------------------------- */
// Send single string 
c.sendCmd(COMMAND_NAME,string);

// Send multiple strings via a single command
c.sendCmdStart(COMMAND_NAME);
c.sendCmdArg(string1);
c.sendCmdArg(string2);
// ...
// ...
c.sendCmdEnd();

##Release Notes

###0.2.4:

  • Added byte data type
  • Binary strings passed back and forth are now explicitly little-endian
  • Added * multiple format flag

##Python Classes

ArduinoBoard 
    Class for connecting to an Arduino board over USB using PyCmdMessenger.  
    The board holds the serial handle (which, in turn, holds the device name,
    baud rate, and timeout) and the board parameters (size of data types in 
    bytes, etc.).  The default parameters are for an ArduinoUno board.

    Static methods
    --------------
    __init__(self, device, baud_rate=9600, timeout=1.0, settle_time=2.0, enable_dtr=False, int_bytes=2, long_bytes=4, float_bytes=4, double_bytes=4)
        Serial connection parameters:
            
            device: serial device (e.g. /dev/ttyACM0)
            baud_rate: baud rate set in the compiled sketch
            timeout: timeout for serial reading and writing
            settle_time: how long to wait before trying to access serial port
            enable_dtr: use DTR (set to False to prevent arduino reset on connect)

        Board input parameters:
            int_bytes: number of bytes to store an integer
            long_bytes: number of bytes to store a long
            float_bytes: number of bytes to store a float
            double_bytes: number of bytes to store a double

        These can be looked up here:
            https://www.arduino.cc/en/Reference/HomePage (under data types)

        The default parameters work for ATMega328p boards.

    close(self)
        Close serial connection.

    read(self)
        Wrap serial read method.

    readline(self)
        Wrap serial readline method.

    write(self, msg)
        Wrap serial write method.

    Instance variables
    ------------------
    baud_rate

    comm

    device

    double_bytes

    float_bytes

    int_bytes

    int_max

    int_min

    long_bytes

    long_max

    long_min

    settle_time

    timeout

    unsigned_int_max

    unsigned_int_min

    unsigned_long_max

    unsigned_long_min

CmdMessenger 
    Basic interface for interfacing over a serial connection to an arduino 
    using the CmdMessenger library.

    Static methods
    --------------
    __init__(self, board_instance, commands, field_separator=',', command_separator=';', escape_separator='/', warnings=True)
        Input:
        board_instance:
            instance of ArduinoBoard initialized with correct serial 
            connection (points to correct serial with correct baud rate) and
            correct board parameters (float bytes, etc.)

        commands:
            a list or tuple of commands specified in the arduino .ino file
            *in the same order* they are listed there.  commands should be
            a list of lists, where the first element in the list specifies
            the command name and the second the formats for the arguments.
            (e.g. commands = [["who_are_you",""],["my_name_is","s"]])

        field_separator:
            character that separates fields within a message
            Default: ","

        command_separator:
            character that separates messages (commands) from each other
            Default: ";" 

        escape_separator:
            escape character to allow separators within messages.
            Default: "/"

        warnings:
            warnings for user
            Default: True

        The separators and escape_separator should match what's
        in the arduino code that initializes the CmdMessenger.  The default
        separator values match the default values as of CmdMessenger 4.0.

    receive(self, arg_formats=None)
        Recieve commands coming off the serial port. 

        arg_formats is an optimal keyword that specifies the formats to use to
        parse incoming arguments.  If specified here, arg_formats supercedes
        the formats specified on initialization.

    send(self, cmd, *args)
        Send a command (which may or may not have associated arguments) to an 
        arduino using the CmdMessage protocol.  The command and any parameters
        should be passed as direct arguments to send.  

        arg_formats is an optional string that specifies the formats to use for
        each argument when passed to the arduino. If specified here,
        arg_formats supercedes formats specified on initialization.

    Instance variables
    ------------------
    board

    command_separator

    commands

    escape_separator

    field_separator

    give_warnings

pycmdmessenger's People

Contributors

harmsm avatar waspinator avatar

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  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  avatar  avatar  avatar  avatar  avatar

pycmdmessenger's Issues

example throws error

the first exchange "who_are_you" works fine, however for the sequence

c.send("sum_two_ints",4,1)
msg = c.receive()

python 3.6 throws this error on the receive line:
struct.error: unpack requires a buffer of 2 bytes

New datatype "byte"

Hi Mike,

I noticed that I cannot exchange "bytes" as integers between 0 and 255. They are handy to save a bit of dynamic memory on the Genuino. Here are the changes (sorry, no diff...):

        self._send_methods = {"c":self._send_char,
                              "b":self._send_byte,
                              "i":self._send_int,
        self._recv_methods = {"c":self._recv_char,
                              "b":self._recv_byte,
                              "i":self._recv_int,
    def _send_byte(self,value):
        """
        Convert a numerical value into an integer, then to a byte object. Check
        bounds for byte.
        """

        # Coerce to int. This will throw a ValueError if the value can't
        # actually be converted.
        if type(value) != int:
            new_value = int(value)

            if self.give_warnings:
                w = "Coercing {} into int ({})".format(value,new_value)
                warnings.warn(w,Warning)
                value = new_value

        # Range check
        if value > 255 or value < 0:
            err = "Value {} exceeds the size of the board's byte.".format(value)
            raise OverflowError(err)

        return struct.pack("b",value)
    def _recv_byte(self,value):
        """
        Recieve a byte in binary format, returning as python int.
        """

        return struct.unpack("b",value)[0]

Maybe you want to include it in your code...

Cheers,
Stephan

Endian mismatch

Hi Mike,

Finally I got my Yún working with PyCmdMessenger (see #15). The last stumbling block was that the integer value of 1 became 256 on the Yún (and 2 became 512 – you get the picture). It looks like the Yún is big endian!

I put a < in front of all the INTEGER_TYPE, UNSIGNED_INTEGER_TYPE and FLOAT_TYPE definitions as mentioned in https://docs.python.org/2/library/struct.html#byte-order-size-and-alignment. The relevant part in arduino.py becomes now:

        INTEGER_TYPE = {2:"<h",4:"<i",8:"<l"}
        UNSIGNED_INTEGER_TYPE = {2:"<H",4:"<I",8:"<L"}
        FLOAT_TYPE = {4:"<f",8:"<d"}

I hope it does not have negative side-effects on PCs.

Cheers,
Stephan

Bug introduced with multiformat commit

Commit 13d43cf introduced a new bug: format argument can not be None anymore. Changing None to "" made my code work. Fixes: fix code or update documentation

ERROR:CmdEvents:Traceback (most recent call last):
  File "E:\projects\iot\iot-project\gateway\CmdEvents\CmdEvents.py", line 25, in run
    message = self.cmdMessenger.receive()
  File "E:\projects\iot\iot-project\gateway\PyCmdMessenger\PyCmdMessenger.py", line 280, in receive
    arg_format_list = self._treat_star_format(arg_format_list,fields[1:])
  File "E:\projects\iot\iot-project\gateway\PyCmdMessenger\PyCmdMessenger.py", line 306, in _treat_star_format
    num_stars = len([a for a in arg_format_list if a == "*"])
TypeError: 'NoneType' object is not iterable

DTR status not set

I fail to see how the self.enable_dtr is forwarded to the Serial connection, since we no longer call self.comm.setDtr() beyond this commit 02124aa.

In Windows (at least), instantiating Arduino with enable_dtr=False (which is the default) does not prevent the Arduino from resetting, as the DTR flag is still set to True on the Serial connection:

self.dtr = self.enable_dtr

This is validated by checking for self.comm.dtr after the Serial port has already been open.

Non-blocking Listener

Could be a good idea to implement CmdMessenger.receive as an asynchronous task, that way tasks don't get blocked listening for a response. PySerial has started a Pyserial-Asyncio client.

Python 2.x compatibility

Hi Mike,

Some time ago, I had the same problem as @zlite. My solution does keep the same functionality in Python 3.x, but is compatible with 2.x;

There is only one change in PyCmdMessenger.py and the diff is:

@@ -116,7 +116,7 @@
                               "?":self._recv_bool,
                               "g":self._recv_guess}
 
-    def send(self,cmd,*args,arg_formats=None):
+    def send(self,cmd,*args,**kwargs):
         """
         Send a command (which may or may not have associated arguments) to an
         arduino using the CmdMessage protocol.  The command and any parameters
@@ -127,6 +127,10 @@
         arg_formats supercedes formats specified on initialization.
         """
 
+        arg_formats = kwargs.pop('arg_formats', None)
+        if kwargs:
+            raise TypeError("'send()' got unexpected keyword arguments: {}".format(', '.join(kwargs.keys())))
+
         # Turn the command into an integer.
         try:
             command_as_int = self._cmd_name_to_int[cmd]

Maybe the setup.py must also be changed.

I don't know if you want to incorporate it into you code. I can understand it if you don't want to keep backward compatibility. Maybe you just want to add a comment what has to be changed for Python 2.x?

Best wishes,
Stephan

type sizes use wrong assumption

I'm using a freescale ARM micro controller with:
char, signed char, and unsigned char are 8 bits;
The plain char type is unsigned by default;
short and unsigned short are 16 bits;
int and unsigned int are 32 bits;
long and unsigned long are 32 bits;
pointers are 32 bits;
long long and unsigned long long are 64 bits;
float is 32 bits;
double is 64 bits;
long double is 64 bits.

Anyway, the kBInt16 test fails because the receive method is still expecting 4 bytes. The 'i' format spec in the python struct documentation is to unpack 4 bytes. I'm confused how this test worked for anyone. With a '16' in the type name you'd think it would only be 2 bytes. The rest of the tests (except the multivalue) pass when I comment out the kBInt16 test.

Unneeded imports

Hi Mike,

There are two unneeded imports in PyCmdMessenger.py: serial and multiprocessing.

Would it make sense to remove them? (It works for me on Python 2.7)

Stephan

Arduino Yun

I developed and tested the CmdMessenger communication on this set-up:
PyCmdMessenger: Linux
CmdMessenger: Arduino Uno
Connection: USB (Serial)
After I got everything working, I transferred the Python program and the sketch to the Arduino Yun:
PyCmdMessenger: Yun
CmdMessenger: microprocessor on the Yun
Connection: Serial, pins 0+1 (Serial1)

Now the CmdMessenger cannot connect to the PyCmdMessenger anymore. Do you have any idea what might go wrong??

Thank you for your help!
Stephan

Python 2.7 decoding problem

Hi Mike,

I had to change the line 624 in PyCmdMessenger.py to get it working:

             w = "Warning: Guessing input format for {}. This can give wildly incorrect values. Consider specifying a format and sending binary data.".format(value)
             warnings.warn(w,Warning)
 
-        tmp_value = value.decode()
+        tmp_value = value.decode('utf-8')
 
         try:
             float(tmp_value)

I don't know what caused it. I use PyCmdMessenger in Python 2.7 and all files have the following headers:

#!/usr/bin/env python2
# -*- coding: utf-8 -*-

from __future__ import unicode_literals

I have to admit, that the unicode stuff is not my strong point ;-), so I have no idea why it's needed in Python 2.x with from __future__ import unicode_literals, but not in Python 3.x!! I also don't have any idea what effect it might have on Python 3.x...

Stephan

Typo

Hi Mike,

There is a stupid typo throughout your code: recieve should actually be receive. Not that it changes the functionality of your code!!

Stephan

c.receive() returns None

In my example every 2nd command sent to the arduino returns None, every other shows the correct message.

AttributeError: module 'PyCmdMessenger' has no attribute 'ArduinoBoard'

Hi,

Thanks for creating PyCmdMessenger, it's been working great for me and really makes my product possible.

I've just setup a new Ubuntu VM running inside of VMware Workstation 15 Player. I installed python 3.6.9 I installed tkinter, pip3, and then PyCmdMessenger. When I run my program I get AttributeError: module 'PyCmdMessenger' has no attribute 'ArduinoBoard'. I'm relatively new to Linux and python programming, so it's likely I'm doing something that's obviously wrong to others.

dmurphy@ubuntu~$ python3 -V
Python 3.6.9
dmurphy@ubuntu~$ sudo apt install python3-pip
dmurphy@ubuntu~$ sudo apt-get install python3-tk
dmurphy@ubuntu~$ pip3 install PyCmdMessenger
dmurphy@ubuntu~$ find / -name PyCmdMessenger 2>/dev/null
/home/dmurphy/.local/lib/python3.6/site-packages/PyCmdMessenger
dmurphy@ubuntu~/dev/python/PasswordPump$ python3 PassPumpGUI_v0_7.py
/dev/ttyS0: ttyS0
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/init.py", line 1705, in call
return self.func(*args)
File "PassPumpGUI_v0_7.py", line 147, in clickedOpen
arduino = PyCmdMessenger.ArduinoBoard(port, baud_rate=115200, timeout=5.0, settle_time=2.0, enable_dtr=False,
AttributeError: module 'PyCmdMessenger' has no attribute 'ArduinoBoard'

Also:
dmurphy@ubuntu~$ find / -name site-packages 2>/dev/null
/snap/python38/22/lib/python3.8/site-packages
/home/dmurphy/.local/lib/python3.6/site-packages

I read another similar thread here and it seemed to indicate that I need to install PyCmdMessenger under /snap/python38/22/lib/python3.8/site-packages, however when I try to copy the PyCmdMessenger directory to /snap/python38/22/lib/python3.8/site-packages, it fails and claims that it's a read only directory. I really have no idea if it's the right fix.

I also tried copying PyCmdMessenger-0.2.4.dist-info and PyCmdMessenger from /home/dmurphy/.local/lib/python3.6/site-packages to /usr/local/lib/python3.6/dist-packages, and that didn't work.

Thanks for the help and the tool!!

Dan
https://github.com/seawarrior181

Add ability to receive byte strings

Right now, it is impossible to receive arbitrary byte-strings.

I wrote a simple setup where my python-script sends the character '\xff' and the Arduino sends that back.

When a string is received where any characters are larger than 127, the receive() method fails:

  File "[...]", line 20, in <module>
    main()
  File "[...]", line 15, in main
    response = messenger.receive()
  File "[...]\Python\Python36-32\lib\site-packages\PyCmdMessenger\PyCmdMessenger.py", line 284, in receive
    received.append(self._recv_methods[arg_format_list[i]](f))
  File "[...]\Python\Python36-32\lib\site-packages\PyCmdMessenger\PyCmdMessenger.py", line 593, in _recv_string
    s = value.decode('ascii')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)

So I propose adding the format character 'B' to indicate a byte string. This will receive the byte string just like _recv_string does, but will just return it without decoding it or stripping any character.

For sending, behaviour should be equivalent to 's' as that already works perfectly fine.

I'll implement this and create a pull request when I'm done.

Sending command via Arduino USB port causes reset (DTR)

Continued from: thijse/Arduino-CmdMessenger#11

When I send a simple acknowledge type message to the Arduino through the built-in USB/Serial interface it causes a reset of the Arduino.
However if I connect a external USB/Serial convertor directly to the Tx/Rx pins of the Arduino then it works , no problem.
The Arduino USB/Serial port works normally when not using CmdMessenger (ie for looking at debugging messages in tera term).

I suspect it is due to the DTR line being toggled on opening the connection.
I did try adding in a self.comm.setDTR(value) into the arduino.py of PyCmdMessenger but I think that was only having an affect after the port was opened (and after the reset had occurred).

c.readStringArg() error

error: array must be initialized with a brace-enclosed initializer
char arr[128] = c.readStringArg();

Unable to Run the Python Code in Windows with PyCmdMessenger

I need some help here. I have cloned the library of PyCmdMessenger in my project folder. There are three modules - PyCmdMessenger.py , arduino.py and init.py.

I am using the test example to instantiate the arduino object -

self.arduino = PyCmdMessenger.ArduinoBoard("/dev/ttyACM0",baud_rate=9600)

And while trying to run it gives the error -

Traceback (most recent call last):
File "C:\Users\Kriti\Desktop\Projects\Python\Transformer Controller\mainThread.py", line 111, in initialize
config.comm.append(Communication())
File "C:\Users\Kriti\Desktop\Projects\Python\Transformer Controller\communication.py", line 8, in init
self.arduino = PyCmdMessenger.ArduinoBoard("/dev/ttyACM0",baud_rate=9600)
AttributeError: 'module' object has no attribute 'ArduinoBoard'

Could you please let me know what am I missing. I am working in windows platform.

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.