HM-TRP Gateway

  • Hi guys,
    i'm just getting started with mysensors, and i'm really impressed with the whole concept, much appreciation to the whole team involved.

    I have a couple of HM-TRP transceiver modules and Arduino nanos. I'd like to build a gateway and sensor nodes with the HM-TRP transceiver. I've looked intensively at all the examples here and i havent found any close to what i want to build, because most of them deal with radios connected via SPI. My radio will be connected via UART operating at 869MHz

    Below is a schematic on how to connect the trasnsceiver to the µC

    If someone could guide me through on how to integrate this transceiver to mysensors i'd really appreciate

    Thanks and best regards,

  • Mod

    @chanky Hi there and welcome to the forum!
    I'm afraid your radios aren't supported by MySensors, that's why you couldn't find any documentation on them.

  • @chanky said in HM-TRP Gateway:

    HM-TRP transceiver

    Look at "MyTransportRS485.cpp and try adapt for your module which has serial communication too.
    Initialize your module in "bool transportInit(void)" ?

    And etc.

    A lot of work .....

  • Hi guys,
    thanks for the quick response, ill have a look at MyTransportRS485.cpp and see how i can adapt.

    Thanks and best regards


  • Hi guys im currently looking at the MyTransportRS485 module so that i can create a new module for HM-TRP and im just not getting how _serialProcess() should work, may be there is something im over looking so i need your help.

    In the case 0 below , the memcpy copies 5 bytes from the address of_header[1] to the address of _header[0] ,

    _header is only declared globally but never written (apart from the fifth element which is fed with the value of inch after memcpy). So when the "if" statement is evaluated for the first time the content of the array could be anything. Shouldn't _header[] be initialised and filled before _serialProcess() is called first?

    // Receiving header information
    char _header[6];
    bool _serialProcess()
    	unsigned char i;
    	if (!_dev.available()) {
    		return false;
    	while(_dev.available()) {
    		char inch;
    		inch =;
    		switch(_recPhase) {
    		// Case 0 looks for the header.  Bytes arrive in the serial interface and get
    		// shifted through a header buffer.  When the start and end characters in
    		// the buffer match the SOH/STX pair, and the destination station ID matches
    		// our ID, save the header information and progress to the next state.
    		case 0:
    			_header[5] = inch;
    			if ((_header[0] == SOH) && (_header[5] == STX) && (_header[1] != _header[2])) {
    				_recCalcCS = 0;
    				_recStation = _header[1];
    				_recSender = _header[2];
    				_recCommand = _header[3];
    				_recLen = _header[4];
    				for (i=1; i<=4; i++) {
    					_recCalcCS += _header[i];
    				_recPhase = 1;
    				_recPos = 0;
    				//Avoid _data[] overflow
    				if (_recLen >= MY_RS485_MAX_MESSAGE_LENGTH) {
    				//Check if we should process this message
    				//We reject the message if we are the sender
    				//We reject if we are not the receiver and message is not a broadcast
    				if ((_recSender == _nodeId) ||
    				        (_recStation != _nodeId &&
    				         _recStation != BROADCAST_ADDRESS)) {
    				if (_recLen == 0) {
    					_recPhase = 2;
    		// Case 1 receives the data portion of the packet.  Read in "_recLen" number
    		// of bytes and store them in the _data array.
    		case 1:
    			_data[_recPos++] = inch;
    			_recCalcCS += inch;
    			if (_recPos == _recLen) {
    				_recPhase = 2;
    		// After the data comes a single ETX character.  Do we have it?  If not,
    		// reset the state machine to default and start looking for a new header.
    		case 2:
    			// Packet properly terminated?
    			if (inch == ETX) {
    				_recPhase = 3;
    			} else {
    		// Next comes the checksum.  We have already calculated it from the incoming
    		// data, so just store the incoming checksum byte for later.
    		case 3:
    			_recCS = inch;
    			_recPhase = 4;
    		// The final state - check the last character is EOT and that the checksum matches.
    		// If that test passes, then look for a valid command callback to execute.
    		// Execute it if found.
    		case 4:
    			if (inch == EOT) {
    				if (_recCS == _recCalcCS) {
    					// First, check for system level commands.  It is possible
    					// to register your own callback as well for system level
    					// commands which will be called after the system default
    					// hook.
    					switch (_recCommand) {
    					case ICSC_SYS_PACK:
    						_packet_from = _recSender;
    						_packet_len = _recLen;
    						_packet_received = true;
    			//Clear the data
    			//Return true, we have processed one command
    			return true;
    	return true;

    Thank you for you help !

    Best regards

  • @chanky

    It is 6 bytes sliding window which is filled from end and compared for correct byte order.
    Here is _header loaded with data:

    _header[5] = inch

    Maybe this helps:

  • @kimot

    Hi thanks for the link now it now clear

  • Hi guys,
    Ive got my changes ready for HM-TRP and id like to test them with arduino, how can i create libraries for arduino? I didnt find any build documentation regarding modified core modules, so if this is documented somewhere im sorry i wasnt able to find this please share the link.
    Thanks and best regards

  • I've figured it out, copying the folder MySensors to <arduino-location>/libraries/

  • Mod

    Great work @chanky

    Would yo mind sharing the code changes, either through a pull request or here in the forum? Maybe others can benefit from and build on your work.

Log in to reply

Suggested Topics

  • 8
  • 1
  • 3
  • 2
  • 90
  • 1