Skip to main content

SMComPy project

Project description

SMCom

SMCom is a communication protocol can work on data link-layer such as UART, SPI or any wireless link-layer communications. This repository provides different implementation in C++ and Python.

SMCom provides node-to-node communication (public-addressable) or private communication from one device to another (private-no address). Users can implement their own communication frame if SMCom's native frames are not adequate.

SMCom requires functions to handle communication channel, which are write & read functions and two callbacks, for user to define.

SMCom :

  • Easy to implement for many devices (Communication between embedded devices or embedded to computers such as ESP32, Arduino boards, Raspberry pi etc.)
  • Low memory budget (User can define their internal buffers)
  • CRC check on messages so data loss can be detected and recovered
  • Provides cross platform communication mainly for embedded devices

API for Python

We provide pip package to download easily on Linux and Windows platforms.

pip install SMComPy

To see a python example: SMWiredPy

API for C++

In order to implement SMCom in C++ projects, see /test folder how to add libraries into Makefile.

SMCom class is a template class implementation which allows to create custom communication frames or provides common scenarios. Two common scenarios is implemented and can be inherited to a new communication class, see an example below.

In order to use the library, a new class must be defined which is inherited from SMCom<SMCOM_PUBLIC> or SMCom<SMCOM_PRIVATE> types, or can be defined with desired fields.

SMCom frames

  1. SMCOM_PUBLIC FRAME
//SMCOM_PUBLIC frame
  1B    1B        4bit       4bit    6bit    2bit       1B     1B    1B
┌─────┬──────┬───────────┬────────┬───────┬───────┬────┬─────┬─────┬─────┐
StartData  TransmitterReceiverMessageMessageDataCRC-HCRC-LEnd  
Byte Length    ID        ID    Index   Type               Byte 
└─────┴──────┴───────────┴────────┴───────┴───────┴────┴─────┴─────┴─────┘
 0xFB  0-255     0-13       0-13    0-60     ..     ..   ..     ..   0xBF
  • Start byte and end byte are both fixed

  • Data length is 1 byte so up to 255 bytes can be send in one SMCom packet

  • Address field

    • SMCOM_PUBLIC uses 4-bit addresses for receiver and transmitters. In 4-bit address scheme (available 2^4 = 16 communication nodes) Two addresses are predefined and cannot be used, so up to 14 node-to-node communication SMCOM_PUBLIC can be used.

    • 0x00-0x0D user defined

    • 0x0E is used for default address (reserved)

    • 0x0F is used for public address (reserved)

  • Message index is 6-bit and some of them are reserved for internal SMCom communications, 60 message id is allowed for users

See public_node for more examples and sample codes

  1. SMCOM_PRIVATE FRAME

SMCOM_PRIVATE frame is the same as above but without transmitter and receiver address fields. See private_node for more examples and sample codes

//SMCOM_PRIVATE
  1B    1B      6bit    2bit       1B     1B    1B
┌─────┬──────┬───────┬───────┬────┬─────┬─────┬─────┐
StartData  MessageMessageDataCRC-HCRC-LEnd  
Byte Length Index   Type               Byte 
└─────┴──────┴───────┴───────┴────┴─────┴─────┴─────┘
 0xFB  0-255   0-60    ..      ..   ..     ..   0xBF
  1. CUSTOM FRAME

Since SMCom is a template library, it supports custom headers. Users can put whatever they want in the frame and can send their own packets and configurations etc. You may put random numbers, preambles or addresses etc. In the below picture some fields are requisite, other than custom header field, since SMCom needs to handle messages, data lengths etc.

//Custom packet definition
  1B    1B      6bit    2bit                              1B     1B    1B
┌─────┬──────┬───────┬───────┬──────────────────────┬────┬─────┬─────┬─────┐
StartData  MessageMessage  Custom header field DataCRC-HCRC-LEnd  
Byte Length Index   Type     (user defined)                  Byte 
└─────┴──────┴───────┴───────┴──────────────────────┴────┴─────┴─────┴─────┘
  0xFB  0-255   0-60   ...                            ..   ..     ..   0xBF

See custom_node for more examples and sample codes

Example class declaration

class my_device : public SMCom<SMCOM_PUBLIC>{
public:
    my_device(uint16_t rx_buffer_size, uint16_t tx_buffer_size, uint8_t id);
    SMCom_Status_t __write__(const uint8_t * buffer, uint16_t len);
	SMCom_Status_t __read__(uint8_t * buffer, uint16_t len);
	size_t __available__();
    void __tx_callback__(SMCom_event_types event, SMCom_Status_t status, const SMCOM_PUBLIC * packet);
    void __rx_callback__(SMCom_event_types event, SMCom_Status_t status, const SMCOM_PUBLIC * packet);
};

Now my_device became a communication class and my_device objects can be used to communication over the channel

my_device my_device_object(1024,1024,0x0B); //Now the current device address is 0x0B
my_device_object.write(0x0A,buffer,len) //To send a message 0x0A
my_device_object.listener() //Can be called inside a while(1) loop or can be called after a byte received event if any

SMCom public functions

  • Constructor family
//Constructors with dynamic buffers
//available only for SMCOM_PRIVATE
SMCom(uint16_t rx_buf_size, uint16_t tx_buf_size, rx_event_handler_callback rx, tx_event_handler_callback tx);

//available only for SMCOM_PUBLIC
SMCom(uint16_t rx_buf_size, uint16_t tx_buf_size, uint8_t id, rx_event_handler_callback rx, tx_event_handler_callback tx);

//Constructors with static buffers
//available only for SMCOM_PRIVATE
SMCom(uint8_t * rx_buffer, uint16_t rx_buf_size, uint8_t * tx_buffer, uint16_t tx_buf_size, rx_event_handler_callback rx, tx_event_handler_callback tx);

//available only for SMCOM_PUBLIC
SMCom(uint8_t * rx_buffer, uint16_t rx_buf_size, uint8_t * tx_buffer, uint16_t tx_buf_size, uint8_t id, rx_event_handler_callback rx, tx_event_handler_callback tx);
  • write function family
//Used for private communications! Receiver address cannot be provided
SMCom_Status_t write(uint8_t message_id, const uint8_t * buffer, uint8_t len, uint8_t retry = 1); 

//Used for public communications
SMCom_Status_t write(uint8_t receiver_id, uint8_t message_id, const uint8_t * buffer, uint8_t len, uint8_t retry = 1);

//Used for public communications, all devices can receive this message
SMCom_Status_t write_public(uint8_t message_id, const uint8_t * buffer, uint8_t len, uint8_t retry = 1);
  • listener function to listen the network This function can be called inside an infinite loop or a task/thread. When listener is called, listener provides necessary checks for SMCom frames and if message is on the line it will call __rx_callback__ function to notify the user.
	SMCom_Status_t listener(void);

In order to call listener, user must provide __read__ and __available__ functions

SMCom class overrideable functions

SMCom requires some main functions to write to actual port, or read from the port etc. In order SMCom to know this user must provide some of the functions definition and must call the communicaton channles write/read functions inside these definitions. Thus, when SMCom tries to write to port it will call its own function which is defined by the user and the actual port write function will be called as desired.

These functions are specifically defined in two underscores such as __FunctionName___.

  • __write__, this function writes the desired data to actual communication channel. SMCom requires child class to override this function! For example if SMCom is used over UART, in user's new defined __write__ function serial.write function must be called.
SMCom_Status_t __write__(const uint8_t * buffer, uint16_t len);
  • __read__, this function reads data from the actual channel. User must provide the defined of this function and must call channel's own read function such as Serial.read
SMCom_Status_t __read__(uint8_t * buffer, uint16_t len);
  • __available__, some communication channels provide available bytes in their queue, buffer or DMA etc. This can be overrided for
size_t __available__();

Note : __write__, __read__ and __available__ definition is mandatory!, SMCom listener function requires read and available functions so if listener will be used, the definition of __read__ and __available__ are necessary to implement.

  • __rx_callback__, when bytes are read and message is decoded internal library calls this function to notify user there is a message on the network. The incoming message can be accessed via const SMCOM_PUBLIC * packet variable.
void __rx_callback__(SMCom_event_types event, SMCom_Status_t status, const SMCOM_PUBLIC * packet);
  • __tx_callback__, when bytes are written to the port and the message is coded, internal library calls this function to notify user desired message is put on the network. (Optional to define)
void __tx_callback__(SMCom_event_types event, SMCom_Status_t status, const SMCOM_PUBLIC * packet);

Example definitions :

A Serial library in different languages are good example to provide and see how to define such functions. Assuming the communication channel is UART so we need to call Serial library's write,read and available functions inside our definitions.

SMCom_Status_t __write__(const uint8_t * buffer, uint16_t len){
	//We write to the serial
	if(Serial.write(buffer, len) == len){
		return SMCom_Status_t::SUCCESS;
	}
	return return SMCom_Status_t::ERROR;
}
SMCom_Status_t __read__(const uint8_t * buffer, uint16_t len){
	//We read from the serial
	if(Serial.readBytes(buffer, len) == len){
		return SMCom_Status_t::SUCCESS;
	}
	return return SMCom_Status_t::ERROR;
}
size_t __available__(){
	return Serial.available();
}
void __rx_callback__(SMCom_event_types event, SMCom_Status_t status, const SMCOM_PUBLIC * packet){
    printf("Packet length %d\n",packet->data_len);
	printf("Message Id:[%d] invoked! Transmitter id[%d], Receiver id[%d]\n",packet->message_id,packet->transmitter_id,packet->receiver_id);
	uint8_t * data = packet->data;
    switch(packet->message_id){
        /*
			Handle different message id's here
		*/
    }
}

SMCom is developed by Sensemore

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

SMComPy-1.0.4.tar.gz (18.4 kB view details)

Uploaded Source

Built Distributions

SMComPy-1.0.4-cp39-cp39-win_amd64.whl (91.4 kB view details)

Uploaded CPython 3.9 Windows x86-64

SMComPy-1.0.4-cp37-cp37m-win_amd64.whl (129.0 kB view details)

Uploaded CPython 3.7m Windows x86-64

File details

Details for the file SMComPy-1.0.4.tar.gz.

File metadata

  • Download URL: SMComPy-1.0.4.tar.gz
  • Upload date:
  • Size: 18.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.6.4 pkginfo/1.7.1 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.56.0 CPython/3.8.10

File hashes

Hashes for SMComPy-1.0.4.tar.gz
Algorithm Hash digest
SHA256 c3030289bf24b7f140c42d711a2d68f3d434d7e7a490c1b8250cd23df81b120f
MD5 734e8fc3d0a0ab9ca2a15aa9f532cbe5
BLAKE2b-256 833ec29df4b1c29735e53531f80a64cff67cba34109598417b2b4a411b295e9a

See more details on using hashes here.

File details

Details for the file SMComPy-1.0.4-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: SMComPy-1.0.4-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 91.4 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.6.4 pkginfo/1.7.1 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.56.0 CPython/3.8.10

File hashes

Hashes for SMComPy-1.0.4-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 53de7d15fbeee292cb3232a422b2c3abda317bf209dc89ec80429f57bf15bf3e
MD5 9d26f932a44a1f5be85391143a4ceb93
BLAKE2b-256 285fc24d4796facd85299f4e3f6649eb52b3961ab8b55f9e5a07bb34761952ad

See more details on using hashes here.

File details

Details for the file SMComPy-1.0.4-cp37-cp37m-win_amd64.whl.

File metadata

  • Download URL: SMComPy-1.0.4-cp37-cp37m-win_amd64.whl
  • Upload date:
  • Size: 129.0 kB
  • Tags: CPython 3.7m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.6.4 pkginfo/1.7.1 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.56.0 CPython/3.8.10

File hashes

Hashes for SMComPy-1.0.4-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 68ea88f5d10c27ffc2e7d5a50f52449441789987e74b6fad59dc661eba4a736f
MD5 9045d6200d0db3bebf20769a98d45142
BLAKE2b-256 8123b71e58f0fe51c5a088a60afbb126bbaada3e77314b1d225275c26ea2c1aa

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page