bittailor / BtMqttSn

Arduino library for an MQTT-SN client communicating over an nRF24L01+ Transceiver.
MIT License
35 stars 3 forks source link

Arduino client !! stuck at the try to connect #1

Closed rougeo closed 7 years ago

rougeo commented 7 years ago

Hello I am trying to use this program on an arduino with xbee module, but the program is stucked at the "try to connect message"

Any idea ?

bittailor commented 7 years ago

Hi

The library uses a nRF24L01+ Transceiver (They can easily be obtained via eBay and many other places for prices as low as $2.)

I never used XBee modules but you could make another implementation of the I_RfPacketSocket interface for XBee stack and then change the stack setup inside MqttSnClient

      Bt::PlacementPointer<Bt::Pin> mChipEnable;
      Bt::PlacementPointer<Bt::Pin> mChipSelect;
      Bt::PlacementPointer<Bt::Spi> mSpi;
      Bt::PlacementPointer<Bt::Rf24Device> mDevice;
      Bt::PlacementPointer<Bt::Rf24Controller> mController;
      Bt::PlacementPointer<Bt::Rf24NetworkSocket> mNetworkSocket;
      Bt::PlacementPointer<Bt::Rf24PacketSocket> mPacketSocket;
      Bt::PlacementPointer<Bt::MqttSnClient> mClient;
rougeo commented 7 years ago

Thank you !! I will try this !!!

rougeo commented 7 years ago

do you have any code that will help me to build a mqtt-sn publish packet then just write to the serial port ??

bittailor commented 7 years ago

Currently the structs and the code that do the serialization and deserialization are in the Bt_MqttSnClient.cpp file and therefore not accessible from outside.

Eclipse Paho lately has added some MQTT-SN support so if you just need in MQTT-SN packet serialization and deserialization have a look at MQTTSNPacket code from Paho.

Or implement the I_RfPacketSocket against a Arduino Stream like this

class SerialPacketSocket : public Bt::I_RfPacketSocket {

   public:
      SerialPacketSocket(Stream& iStream): mStream(&iStream) {
      }

      virtual bool send(uint8_t* iPayload, size_t iSize, uint8_t iNodeId ) {
         return mStream->write(iPayload,iSize) == iSize;
      }

      virtual int32_t receive(uint8_t* oPayload, size_t iMaxSize, uint8_t* oNodeId) {
         int32_t size = 0;
         while(mStream->available() > 0) {
            oPayload[size] = mStream->read();
            size++;
            if(size >= iMaxSize) {
               return size;
            }
         }
         return size;
      }

      virtual bool available() {
         return mStream->available() > 0;
      }

      virtual void suspend() {
      }

      virtual void resume() {
      }

   private:
      Stream* mStream;
};

And then setup the client to use this as socket:

SerialPacketSocket serialPacketSocket(Serial1);
Bt::MqttSnClient client(serialPacketSocket, GATEWAY_NODE_ID, CLIENT_ID, &subscribeCallback);

Here the full example that compiles (did not check that it runs)

/*
   Basic MQTT-SN example 

   - connects to an MQTT-SN gateway
   - reads a string from Serial and publishes the PUBLISH_TOPIC ("Bt/Ex/PubSub/Out") topic
   - subscribes to the SUBSCRIBE_TOPIC ("Bt/Ex/PubSub/In") topic and writes the reiceived data to the Serial 
*/

#include <SPI.h>
#include <BtMqttSn.h>

//-----

#define CLIENT_NODE_ID 1
#define GATEWAY_NODE_ID 0

#define CLIENT_ID "BtMqttPupSubExample"
#define PUBLISH_TOPIC "Bt/Ex/PubSub/Out"
#define SUBSCRIBE_TOPIC "Bt/Ex/PubSub/In"

//-----

class SerialPacketSocket : public Bt::I_RfPacketSocket {

   public:
      SerialPacketSocket(Stream& iStream): mStream(&iStream) {
      }

      virtual bool send(uint8_t* iPayload, size_t iSize, uint8_t iNodeId ) {
         return mStream->write(iPayload,iSize) == iSize;
      }

      virtual int32_t receive(uint8_t* oPayload, size_t iMaxSize, uint8_t* oNodeId) {
         int32_t size = 0;
         while(mStream->available() > 0) {
            oPayload[size] = mStream->read();
            size++;
            if(size >= iMaxSize) {
               return size;
            }
         }
         return size;
      }

      virtual bool available() {
         return mStream->available() > 0;
      }

      virtual void suspend() {
      }

      virtual void resume() {
      }

   private:
      Stream* mStream;
};

//-----

SerialPacketSocket serialPacketSocket(Serial1);
Bt::MqttSnClient client(serialPacketSocket, GATEWAY_NODE_ID, CLIENT_ID, &subscribeCallback);

void setup() {
   Serial.begin(9600);
   Serial << endl << endl << endl << "*** MQTT-SN PubSub example ***" << endl;
   Serial << endl; 
   Serial << " - Node      = " << CLIENT_NODE_ID << endl;
   Serial << " - Pup-Topic = " << PUBLISH_TOPIC << endl;
   Serial << " - Sub-Topic = " << SUBSCRIBE_TOPIC << endl;
   Serial << "try connect ..." << endl;

   while (!client.connect(30)) {
      Serial << "... connect failed ..." << endl;
      delay(1000);   
      Serial << "... retry connect ..." << endl;
   }

   Serial << "... connected" << endl;

   Serial << "subscribe" << endl;

   client.subscribe(SUBSCRIBE_TOPIC);

   Serial << "out> <Start>" << endl;

   client.publish(PUBLISH_TOPIC,"<Start>");

}

void loop() {
   client.loop();     
   if (Serial.available()) {
      String out = readString();
      Serial << "out> " << out << endl;
      client.publish(PUBLISH_TOPIC,out.c_str());
      if (out == "<quit>") {
         quit();
      }
   }
}

void subscribeCallback(const char* iTopic, const char*  iData) {
  Serial << "in> " << iData << endl;    
}

String readString() {
  Serial.setTimeout(10);
  String string = Serial.readString();
  Serial.setTimeout(1000);
  return string;
}

void quit() {
   Serial << "<quit>" << endl; 
   client.disconnect();
   Serial << "Hit reboot" << endl; 
   while(true){}  
}
rougeo commented 7 years ago

Hello Thank you for your time and this code !! I did compile it and upload it on an arduino with the xbee module. No error while compiling. But i am using the eclipse rsmb mqtt-sn broker and the mqtt-sn serial bridge from this repo https://github.com/njh/mqtt-sn-tools to forward mqtt-sn packet coming to the serial port.

If i use the command line to send mqtt-sn packet, evrything works fine ok

Yet if i use the serial bridge with the arduino i code i have this message ko

And the arduino serial port on the arduino ide show this message

serial monitor

So i am wondering if it is the serial bridge the probleme. What gateway are you using and how do you forward the mqtt-sn packet to the broker from the serial ???????????

Actually this is my internship project and i am kind of stuck with this part . Thank you !!

bittailor commented 7 years ago

Hi

What kind of Arduino board do you use?

I tried your setup with an Arduino Uno. To do so I had to update my example sketch to use a SoftwareSerial since to Uno has just one Hardware Serial

#include <SoftwareSerial.h>
...
SoftwareSerial Serial1(10, 11);
...

You find my updated example here on a new branch serial-port-bridge-support where I try to fix some other issues I found while using your setup and support the serial bridge use case.

So the hardware setup looks like this:

btmqttsn-serialportbridge

On my machine is start the Serial Port Bridge where /dev/tty.usbserial-A50285BI is the device of the FDTI Adapter.

./mqtt-sn-serial-bridge -dd -p 1884 /dev/tty.usbserial-A50285BI

Broker config looks like this:

# will show you packets being sent and received
trace_output protocol
trace_level maximum

# MQTT listener
listener 1883 INADDR_ANY mqtt

# MQTT-S listener
listener 1884 INADDR_ANY mqtts

With this I was able to connect:

screen shot 2017-04-06 at 23 21 11

The publishing did not work and I found out that the Bit Fields ordering of the Flags byte was wrong but since for my use case I implemented the client and the gateway with the same (wrong) Bit Fields ordering it did not matter. I fixed this on the serial-port-bridge-support branch (see be54c390528be295f3bbfbc32e15c6dc7a4ef0ee). After this also the publish and subscribe worked.

I also tried it with a Adafruit Feather M0 which has a second hardware serial there I saw some problem with the byte alignment padding on ARM MCU's. So it should work on AVR but not on ARM MCU yet.

Hope this helps with internship project.

rougeo commented 7 years ago

Hello Thanks for this update !! i i tried the code this morning !!

I am using the arduino genuino uno with a xbee shield

unnamede

I am using this broker https://github.com/MichalFoksa/rsmb

When i run the code now using the new update i have this answer from the broker :: first

Adn this one from the serial bridge :: second

The thing is the first message sent by the arduino is not a Connect Message but ::

capture2

So what broker are you using on your computer ? Is it a sync or an Asynch gateway ?

Thank you

bittailor commented 7 years ago

Hi

I use "RSMB: Really Small Message Broker" from the eclipse/mosquitto.rsmb repository on GitHub.

When I look at the first message on your Serial Port Bridge 0x0A 0x0A 0x0A 0x0A 0x0A 0x0A 0x2A 0x2A 0x2A 0x20 it's not clear for me where this should come from since the values look not like values the client sends. I added logging to what the SerialPacketSocket on the client sends and receives and this should match what the Serial Port Bridge receives and sends. To enable this logging you must change the define in the /libraries/BtMqttSn/Bt_MqttSnConfiguration.hpp

from

#define BT_LOGGING BT_LOG_LEVEL_ERROR

to

#define BT_LOGGING BT_LOG_LEVEL_DEBUG

So when I do this I see the following on the clients output:

*** MQTT-SN PubSub example ***

 - Node      = 1
 - Pup-Topic = Bt/Ex/PubSub/Out
 - Sub-Topic = Bt/Ex/PubSub/In
try connect ...
send to Serial Bridge > 0x19 0x4 0x4 0x1 0x0 0x1e 0x42 0x74 0x4d 0x71 0x74 0x74 0x50 0x75 0x70 0x53 0x75 0x62 0x45 0x78 0x61 0x6d 0x70 0x6c 0x65 
recv from Serial Bridge < 0x3 0x5 0x0 
473 I: state change from : 0
485 I:              to   : 1
... connected
subscribe
send to Serial Bridge > 0x14 0x12 0x0 0x0 0x0 0x42 0x74 0x2f 0x45 0x78 0x2f 0x50 0x75 0x62 0x53 0x75 0x62 0x2f 0x49 0x6e 
recv from Serial Bridge < 0x8 0x13 0x0 0x0 0x1 0x0 0x0 0x0 
924 I: topic subscribed:
952 I:    id    :1
972 I:    topic :Bt/Ex/PubSub/In
out> <Start>
1022 D: register topic since not registered yet Bt/Ex/PubSub/Out
send to Serial Bridge > 0x16 0xa 0x0 0x0 0x0 0x1 0x42 0x74 0x2f 0x45 0x78 0x2f 0x50 0x75 0x62 0x53 0x75 0x62 0x2f 0x4f 0x75 0x74 
recv from Serial Bridge < 0x7 0xb 0x0 0x2 0x0 0x1 0x0 
1479 I: topic registered:
1506 I:    id    :2
1527 I:    topic :Bt/Ex/PubSub/Out
send to Serial Bridge > 0xe 0xc 0x4 0x0 0x2 0x0 0x0 0x3c 0x53 0x74 0x61 0x72 0x74 0x3e 
31480 I: send PINGREQ ...
send to Serial Bridge > 0x2 0x16 
recv from Serial Bridge < 0x2 0x17 
31703 I:  ... PINGRESP received
61481 I: send PINGREQ ...
send to Serial Bridge > 0x2 0x16 
recv from Serial Bridge < 0x2 0x17 
61709 I:  ... PINGRESP received

And this on the Serial Port Bridge output:

2017-04-08 20:49:10 DEBUG Serial -> UDP (bytes_read=25, type=CONNECT)
  0x19 0x04 0x04 0x01 0x00 0x1E 0x42 0x74 0x4D 0x71 0x74 0x74 0x50 0x75 0x70 0x53 0x75 0x62 0x45 0x78 0x61 0x6D 0x70 0x6C 0x65
2017-04-08 20:49:10 DEBUG Sending  25 bytes. Type=CONNECT on Socket: 3.
2017-04-08 20:49:10 DEBUG waiting for packet...
2017-04-08 20:49:10 DEBUG Received  3 bytes from 127.0.0.1:1884. Type=CONNACK on Socket: 3
2017-04-08 20:49:11 DEBUG Serial -> UDP (bytes_read=20, type=SUBSCRIBE)
  0x14 0x12 0x00 0x00 0x00 0x42 0x74 0x2F 0x45 0x78 0x2F 0x50 0x75 0x62 0x53 0x75 0x62 0x2F 0x49 0x6E
2017-04-08 20:49:11 DEBUG Sending  20 bytes. Type=SUBSCRIBE on Socket: 3.
2017-04-08 20:49:11 DEBUG waiting for packet...
2017-04-08 20:49:11 DEBUG Received  8 bytes from 127.0.0.1:1884. Type=SUBACK on Socket: 3
2017-04-08 20:49:11 DEBUG Serial -> UDP (bytes_read=22, type=REGISTER)
  0x16 0x0A 0x00 0x00 0x00 0x01 0x42 0x74 0x2F 0x45 0x78 0x2F 0x50 0x75 0x62 0x53 0x75 0x62 0x2F 0x4F 0x75 0x74
2017-04-08 20:49:11 DEBUG Sending  22 bytes. Type=REGISTER on Socket: 3.
2017-04-08 20:49:11 DEBUG waiting for packet...
2017-04-08 20:49:11 DEBUG Received  7 bytes from 127.0.0.1:1884. Type=REGACK on Socket: 3
2017-04-08 20:49:12 DEBUG Serial -> UDP (bytes_read=14, type=PUBLISH)
  0x0E 0x0C 0x04 0x00 0x02 0x00 0x00 0x3C 0x53 0x74 0x61 0x72 0x74 0x3E
2017-04-08 20:49:12 DEBUG Sending  14 bytes. Type=PUBLISH on Socket: 3.
2017-04-08 20:49:41 DEBUG Serial -> UDP (bytes_read=2, type=PINGREQ)
  0x02 0x16
2017-04-08 20:49:41 DEBUG Sending   2 bytes. Type=PINGREQ on Socket: 3.
2017-04-08 20:49:41 DEBUG waiting for packet...
2017-04-08 20:49:41 DEBUG Received  2 bytes from 127.0.0.1:1884. Type=PINGRESP on Socket: 3
2017-04-08 20:50:11 DEBUG Serial -> UDP (bytes_read=2, type=PINGREQ)
  0x02 0x16
2017-04-08 20:50:11 DEBUG Sending   2 bytes. Type=PINGREQ on Socket: 3.
2017-04-08 20:50:11 DEBUG waiting for packet...

So here the first message is 0x19 0x04 0x04 0x01 0x00 0x1E 0x42 0x74 0x4D 0x71 0x74 0x74 0x50 0x75 0x70 0x53 0x75 0x62 0x45 0x78 0x61 0x6D 0x70 0x6C 0x65 (CONNECT) and I see the same message on the Serial Port Bridge.

rougeo commented 7 years ago

Hello, i still have this error on the computer when i run the code !! It's about the socket. The code is compiling but if i plug the arduino then i have this on the computer : 2017-04-27-111745_1280x1024_scrot

bittailor commented 7 years ago

I had a look at the Arduino Wireless SD Shield which I think you are using. I saw that the wireless module actually uses the same Serial pins as the once connected to the USB-to-serial converter. So I expect in your sketch you pass the Serial to the SerialPacketSocket and not the Serial1 or a SoftwareSerial instance. With this you actually mix the logging output and the MQTT-SN messages. And this explains the 0x0A 0x0A 0x0A 0x0A 0x0A 0x0A 0x2A 0x2A which is actually first bytes of the logging output and not a MQTT-SN message (0x0A = New Line and 0x2A = *).

So I think you need to completely disable the logging in the client library by setting the define in the /libraries/BtMqttSn/Bt_MqttSnConfiguration.hpp

from

#define BT_LOGGING BT_LOG_LEVEL_ERROR

to

#define BT_LOGGING BT_LOG_LEVEL_NONE

and remove all the Serial << ... from the Sketch (ino file) so that only the MQTT-SN messages are written to the Serial.

rougeo commented 7 years ago

Hello, thank you !! Now it's working !! i have the connect message !! i removed the Serial << ...