Closed rougeo closed 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;
Thank you !! I will try this !!!
do you have any code that will help me to build a mqtt-sn publish packet then just write to the serial port ??
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){}
}
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
Yet if i use the serial bridge with the arduino i code i have this message
And the arduino serial port on the arduino ide show this message
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 !!
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:
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:
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.
Hello Thanks for this update !! i i tried the code this morning !!
I am using the arduino genuino uno with a xbee shield
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 ::
Adn this one from the serial bridge ::
The thing is the first message sent by the arduino is not a Connect Message but ::
So what broker are you using on your computer ? Is it a sync or an Asynch gateway ?
Thank you
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.
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 :
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.
Hello, thank you !! Now it's working !! i have the connect message !! i removed the Serial << ...
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 ?