mqtt error void callback/subscribed on arduino - arduino

I'm testing with my arduino and MQTT cloud.
For the publish everything goes well, the arduino publishes "hello world"
But with the void callback function nothing happens.
With my MQTT.fx client, I'm subscribed to the topics "status" and "commando".
At the "status" I see that the arduino is a live.
When I publish with my MQTT.fx client to the topic "commando".
I can see it arrived in my client, but not in the serial monitor of the arduino.
Why is the void callback function not used?
#include <SPI.h>
#include <PubSubClient.h>
#include <Ethernet.h>
#define server "m20.cloudmqtt.com"
int port = 13365;
// Update these with values suitable for your network.
byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
byte ip[] = { 192, 168, 0, 120 };
unsigned long time;
char message_buff[100];
EthernetClient ethClient;
PubSubClient client(server, port, callback, ethClient);
void setup()
{
// init serial link for debugging
Serial.begin(115200);
Ethernet.begin(mac, ip);
if (client.connect("arduino-MQTT","test","test")) {
client.publish("/arduino/status/","hello world");
client.subscribe("/arduino/commando/");
Serial.println("Connected");
}
if (Ethernet.begin(mac) == 0)
{
Serial.println("Failed to configure Ethernet using DHCP");
return;
}
}
void loop()
{
// MQTT client loop processing
client.loop();
}
void callback(char* topic, byte* payload, unsigned int length) {
if (strcmp(topic, "/arduino/commando/") == 0) {
String msg = toString(payload, length);
Serial.println(msg);
}else{
Serial.println("arduino topic not found");
}
}
//
// toString function
//
String toString(byte* payload, unsigned int length) {
int i = 0;
char buff[length + 1];
for (i = 0; i < length; i++) {
buff[i] = payload[i];
}
buff[i] = '\0';
String msg = String(buff);
return msg;
}

I have just tested your code with RSMB broker and it works. I do not have DHCP on my computer so I had to comment out DHCP handling code - Ethernet.begin(mac). I think that's where your bug is. Because:
You assign static IP to your Ethernet
Connect to mqtt broker, and subscribe to a topic
Query DHCP for a new IP. Probably at this point your Arduino gets a different IP than statically configured and the broker cannot reach your Arduino any more to publish subscribed topic.
Fix your Ethernet handling code. I like this formula:
// Start the Ethernet connection:
Serial.println(F("Querying DHCP"));
if ( Ethernet.begin( mac ) == 0 ) {
Serial.println(F("DHCP failed, fallback to static IP"));
// When DHCP fails, fallback to static configuration ;
Ethernet.begin( mac, ip ) ;
}
printIp() ;
And printIp function:
void printIp() {
// Print local IP address
Serial.print(F("My IP "));
for (byte thisByte = 0; thisByte < 4; thisByte++) {
// print the value of each byte of the IP address:
Serial.print(Ethernet.localIP()[thisByte], DEC);
Serial.print('.');
}
}

Related

RabbitMQ with Arduino Uno

I'm using RabbitMQ with Arduino for the first time and I need to publish data. So I've used the PubSubCLient class. This is the code:
#include <SPI.h>
#include <PubSubClient.h>
#include <Dhcp.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Dns.h>
#include <EthernetServer.h>
#include <EthernetClient.h>
//declare variables
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xDE, 0xDE, 0xDD };
byte server[] = { 127, 0, 0, 1 };
byte ip[] = { 192, 168, 1, 22 };
String stringone = "localhost";
void callback(char* topic, byte* payload, unsigned int length) {
Serial.println(topic);
//convert byte to char
payload[length] = '\0';
String strPayload = String((char*)payload);
Serial.println(strPayload);
int valoc = strPayload.lastIndexOf(',');
String val = strPayload.substring(valoc+1);
Serial.println(val);
}
EthernetClient ethClient;
PubSubClient client(server, 5672, callback, ethClient);
void setup() {
// client is now configured for use
Serial.begin(9600);
Serial.println("==STARTING==");
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
// try to congifure using IP address instead of DHCP:
Ethernet.begin(mac, ip);
}
// give the Ethernet shield a second to initialize:
delay(1000);
Serial.println("connecting...");
for (byte thisByte = 0; thisByte < 4; thisByte++) {
// print the value of each byte of the IP address:
Serial.print(Ethernet.localIP()[thisByte], DEC);
Serial.print(".");
}
boolean con = client.connect("arduinoMQTT123");
while(con != 1) {
Serial.println("no con-while");
con = client.connect("arduinoMQTT123");
}
if(con) {
Serial.println("got con");
client.subscribe("/v2/feeds/FEED_ID.csv");
} else Serial.println("no con");
}
void loop() {
client.loop();
}
I keep getting an error, no connection. I think that's because I don't know how to use Arduino with RabbitMQ.
These two lines are the source of your troubles:
byte server[] = { 127, 0, 0, 1 };
...
PubSubClient client(server, 5672, callback, ethClient);
server[] must specify the address of your RabbitMQ server. 127.0.0.1 is the address for localhost. This is never routable.
Additionally, PubSubClient is an MQTT client, not a RabbitMQ (AMQP) client. Therefore, the AMQP port you specified, 5672, will not work.
You need to enable and configure the MQTT adapter in RabbitMQ and then use the appropriate MQTT port, typically 1883.

Message is not publishing to ESP8266 from IBM Bluemix

I have programmed to my ESP8266 and subscribed one topic to keep listening messages. This is my graphical view of injecting message to IBM Iot node.
This is my settings of inject view
This is my settings of IBM Iot node.
Here are my logs at Serial Monitor, it is connected and subscribed to cmd channel
So far so good, When I am trying to inject a message to my IBM Iot node then it is not publishing a message, as it is not reaching on serial monitor and no log on debug view. here you can see
Here is source code:
#include <ESP8266WiFi.h>
#include <PubSubClient.h> // https://github.com/knolleary/pubsubclient/releases/tag/v2.3
const char* ssid = "shiv";
const char* password = "manmohan#12345";
#define ORG "2kafk4"
#define DEVICE_TYPE "ESP8266"
#define DEVICE_ID "5CCF7FEED6F0"
#define TOKEN "opKF7v3#8jRM*mGkb_"
char server[] = ORG ".messaging.internetofthings.ibmcloud.com";
char topic[] = "iot-2/cmd/test/fmt/String";
char authMethod[] = "use-token-auth";
char token[] = TOKEN;
char clientId[] = "d:" ORG ":" DEVICE_TYPE ":" DEVICE_ID;
WiFiClient wifiClient;
void callback(char* topic, byte* payload, unsigned int payloadLength) {
Serial.print("callback invoked for topic: "); Serial.println(topic);
for (int i = 0; i < payloadLength; i++) {
Serial.print((char)payload[i]);
}
}
PubSubClient client(server, 1883, callback, wifiClient);
void setup() {
Serial.begin(115200);
Serial.println();
wifiConnect();
mqttConnect();
}
void loop() {
if (!client.loop()) {
mqttConnect();
}
}
void wifiConnect() {
Serial.print("Connecting to "); Serial.print(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("nWiFi connected, IP address: "); Serial.println(WiFi.localIP());
}
void mqttConnect() {
if (!client.connected()) {
Serial.print("Reconnecting MQTT client to "); Serial.println(server);
while (!client.connect(clientId, authMethod, token)) {
Serial.print(".");
delay(500);
}
initManagedDevice();
Serial.println();
}
}
void initManagedDevice() {
if (client.subscribe(topic)) {
Serial.println("subscribe to cmd OK");
} else {
Serial.println("subscribe to cmd FAILED");
}
}
I tried to check cloud foundry logs using cf command, here it is https://pastebin.com/dfMaS1Gd
Can anyone hint me what I am doing wrong ? Thanks in advance.
Confirm the device type is correctly specified in your node configuration. Currently the screenshot show 0.16.2 which doesn't seem to match the device type you registered and what is specified in your code.

Publish onto Mosquitto broker running on laptop

I have followed the steps outlined in the following link to install and run the Mosquitto broker on my laptop.
https://sivatechworld.wordpress.com/2015/06/11/step-by-step-installing-and-configuring-mosquitto-with-windows-7/
I have tested the publishing and subscription events using command line i.e, the mosquitto_pub and mosquitto_sub commands and they worked fine!
I want to publish to this broker running on my laptop (listening to port 1883 - confirmed using the netstat-an command) using an Arduino which is using the functions from "PubSubClient" library.
For the server's IP address in the Arduino Publish sketch, I have given the IP address of my laptop itself which it gets when it connects to my home network. Following is the publisher code:
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#define CLIENTID "Arsen"
const char topic[] = "tem";
#define POLLINTERVAL 120000
void callback(char* topic, byte* payload, unsigned int length){
//Do nothing as we are publishing ONLY.
}
byte mac [] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED} ;
IPAddress server(192, 168, 0, 10);
EthernetClient ethClient;
PubSubClient arduinoClient(server,1883, callback, ethClient) ;
unsigned long boardTime = 0 ;
float sensedTemperature = 0;
char charTemp [6];
int connRC = 0;
void setup(void) {
Serial.begin(9600);
//Connect to the MQTT server - test.mosquitto.org
beginConnection() ;
}
//Initialise MQTT connection
void beginConnection() {
Serial.begin(9600);
Ethernet.begin(mac) ; //using the address assigned through DHCP
do{
int connRC = arduinoClient.connect(CLIENTID);
}while(connRC==1);
Serial.println("We are connected finally");
delay(5000);
Serial.println(arduinoClient.state());
}
void loop(void) {
boardTime = millis();
if ((boardTime % POLLINTERVAL) == 0) {
getTemp();
dtostrf(sensedTemperature,5,2,charTemp);
boolean rec = arduinoClient.publish(topic, charTemp);
Serial.println(rec);
Serial.println("Successfully published");
}
arduinoClient.loop();
}
void getTemp() {
// Send the command to get temperatures
delay(100);
sensedTemperature = analogRead(2); //temperature sensor at analog pin 2 on Arduino.
Serial.println(sensedTemperature);
delay(150);
}
The subscriber code is:
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <EthernetServer.h>
#include <EthernetClient.h>
#include <Dns.h>
#include <Dhcp.h>
#include <SPI.h>
#include <PubSubClient.h>
#define PIN 13
//MQTT Definition
#define CLIENTID "Aract"
#define TOPICNAME "tem"
byte mac [] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED} ;
IPAddress server(192,168,0,5); // Mosquitto Server
int connRC = 0;
//Handle message from mosquitto and set LEDs
void callback(char* topic, byte* payload, unsigned int length) {
int i=0; char buffer [length];
for(i=0;i<length;i++) {
buffer [i] = char((payload[i]));
}
String payLoadData = buffer;
Serial.println(payLoadData);
setled(payLoadData);
}
//Our MQTT client
EthernetClient ethclient;
PubSubClient arduinoClient(server, 1883, callback, ethclient) ;
void setup() {
//Connect to the MQTT server - test.mosquitto.org
beginConnection() ;
}
//Initialise MQTT connection
void beginConnection() {
Serial.begin(9600);
Ethernet.begin(mac) ;
do{
connRC = arduinoClient.connect(CLIENTID) ;
delay(2000);
}while(connRC==1);
delay(3000);
Serial.println(arduinoClient.state());
if (connRC==1) {
boolean rec = arduinoClient.subscribe(TOPICNAME) ;
Serial.println(rec);
Serial.println("Successfully Subscribed");
} else {
Serial.println("connRC") ;
}
}
void loop()
{
arduinoClient.loop() ;
}
void setled(String s)
{
int temperature;
temperature = s.toInt();
Serial.println(temperature);
if (temperature >= 200){
digitalWrite(PIN, HIGH);
}
else{
digitalWrite(PIN, LOW);
}
}
The Ethernet shield is working well as it successfully executed the example programs. The state function returns "zero" which implies that the board is connecting to the network. However, the publish command returns a boolean value "rec" which is giving false. I want to know as to why this process is being unsuccessful all the time?
The verbose option (-v) along with Mosquitto on command line throws up an unknown error instead of showing the logged details. How to overcome this problem or what exactly is wrong in my technique?
I had faced the same problem and I got the solution as this...
Just go to the services running in your PC and stop the mosquitto-broker, now open the cmd and change the directory to the place where mosuitto files were located (in my case it is "cd C:\Program Files (x86)\mosquitto") and then enter this command mosquitto -v, now just left that window like that (If u closed then it won't work)...
It really worked and the reason why its not working in before case is, when we started moquitto-broker service then its not opening ports for IPv4 and here is the reference "Mosquitto Error"

Arduino Knolleary PubSubClient will publish messages but can't receive them

I am using the Knolleary PubSubClient to make a connection to my MQTT server. I have been able to successfully authenticate and make a connection after not much work. I can even publish messages to topics. However, the issue I am having is that I can subscribe to topics and get no error, but when I publish to that topic (from mosquitto on my Mac) the callback does not get called and the message to the subscribe topic does not appear to be received. I have tried running a mosquitto subscription to the same topic at the same time, and that does receive the published message. Not sure if there is a problem in my callback code or what is going on here. Any help would be appreciated. Arduino code is below:
/*
Basic MQTT example
- connects to an MQTT server
- publishes "hello world" to the topic "outTopic"
- subscribes to the topic "inTopic"
*/
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
// Update these with values suitable for your network.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte server[] = { 10, 2, 63, 123 };
byte ip[] = { 192, 168, 1, 10 };
void callback(char* topic, byte* payload, unsigned int length) {
Serial.println(topic);
//convert byte to char
payload[length] = '\0';
String strPayload = String((char*)payload);
Serial.println(strPayload);
//int valoc = strPayload.lastIndexOf(',');
//String val = strPayload.substring(valoc+1);
//Serial.println(val);
}
EthernetClient ethClient;
PubSubClient client(server, 1883, callback, ethClient);
void setup()
{
Serial.begin(19200);
Serial.println("==STARTING==");
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
// try to congifure using IP address instead of DHCP:
Ethernet.begin(mac, ip);
}
// give the Ethernet shield a second to initialize:
delay(1000);
Serial.println("connecting...");
for (byte thisByte = 0; thisByte < 4; thisByte++) {
// print the value of each byte of the IP address:
Serial.print(Ethernet.localIP()[thisByte], DEC);
Serial.print(".");
}
//delay(500);
boolean con = client.connect("1", "3snzzon5dyade:abc", "OBSCURED_FOR_SEC");
while(con != 1){
Serial.println("no con-while");
con = client.connect("1", "3snzzon5dyade:abc", "OBSCURED_FOR_SEC");
}
//Serial.println(con);
if(con){
Serial.println("got con");
client.publish("testq","hello world");
client.subscribe("testq");
}else Serial.println("no con");
}
void loop()
{
client.loop();
}
Like I said, I can see everything working properly with mosquitto. I have even tried matching up client_ids with no luck. Any help or ideas would be greatly appreciated.
your subscribe topic "testq" must be in an array like
char testq[] = {'t', 'e', 's', 't', 'q', '\0'};
be sure to finisht your array with an ,'\0'
Then you subscribe with:
client.subscribe(testq);

Arduino DHCP error

I'm testing the Ethernet shield with an Arduino Uno, and I'm getting a DHCP error just using the example sketch.
#include <SPI.h>
#include <Ethernet.h>
byte MACaddress[] = { 0x90, 0xAD, 0xDA, 0x0D, 0x96, 0xFE };
EthernetClient client;
void setup() {
Serial.begin(9600);
while (!Serial) {
;
}
// Start the Ethernet connection:
if (Ethernet.begin(MACaddress) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
for(;;)
;
}
Serial.print("My IP address: ");
for (byte thisByte = 0; thisByte < 4; thisByte++) {
Serial.print(Ethernet.localIP()[thisByte], DEC);
Serial.print(".");
}
Serial.println();
}
void loop() {
}
I've opened the router administration page, and I can see it gave the Arduino an IP address, associated with the MAC address. I've also tried a static IP address in the code (Ethernet.begin(MACaddress, IPaddress)), but it won't work either.
I can't ping the shield IP address that shows in the router administrator page.
What is wrong with just this simple code?
Everything is out of the box, the Arduino and the shield. I haven't done anything with them, just connected the shield to the Arduino and sent the code. It seems everything is working fine, the LEDs are blinking for both boards.
These loops are useless.. Could you try something like:
#if defined(ARDUINO) && ARDUINO > 18
#include <SPI.h>
#endif
#include <Ethernet.h>
#include <EthernetDHCP.h>
// MAC Address
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
const char* ip_to_str(const uint8_t*);
// Initialize the Ethernet server library
Server server(8080);
void setup()
{
Serial.begin(9600);
Serial.println("Attempting to obtain a DHCP lease...");
// Initiate a DHCP session. The argument is the MAC (hardware) address that
// you want your Ethernet shield to use. This call will block until a DHCP
// lease has been obtained. The request will be periodically resent until
// a lease is granted, but if there is no DHCP server on the network or if
// the server fails to respond, this call will block forever.
// Thus, you can alternatively use polling mode to check whether a DHCP
// lease has been obtained, so that you can react if the server does not
// respond (see the PollingDHCP example).
EthernetDHCP.begin(mac);
// Since we're here, it means that we now have a DHCP lease, so we print
// out some information.
const byte* ipAddr = EthernetDHCP.ipAddress();
const byte* gatewayAddr = EthernetDHCP.gatewayIpAddress();
const byte* dnsAddr = EthernetDHCP.dnsIpAddress();
Serial.println("A DHCP lease has been obtained.");
Serial.print("My IP address is ");
Serial.println(ip_to_str(ipAddr));
Serial.print("Gateway IP address is ");
Serial.println(ip_to_str(gatewayAddr));
Serial.print("DNS IP address is ");
Serial.println(ip_to_str(dnsAddr));
// Start the server
server.begin();
}
void loop()
{
// You should periodically call this method in your loop(): It will allow
// the DHCP library to maintain your DHCP lease, which means that it will
// periodically renew the lease and rebind if the lease cannot be renewed.
// Thus, unless you call this somewhere in your loop, your DHCP lease might
// expire, which you probably do not want :-)
EthernetDHCP.maintain();
// listen for incoming clients
Client client = server.available();
if (client) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
// Some misc. HTML
client.println("<title>Arduino Control Panel</title>");
client.println("<center><h1>Control Panel</h1></center>");
client.println("<p></p>");
// output the value of each analog input pin
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
client.print("Analog input ");
client.print(analogChannel);
client.print(" is ");
client.print(analogRead(analogChannel));
client.println("<br />");
}
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
}
// Just a utility function to nicely format an IP address.
const char* ip_to_str(const uint8_t* ipAddr)
{
static char buf[16];
sprintf(buf, "%d.%d.%d.%d\0", ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3]);
return buf;
}
I'm not sure what you mean by "I've also tried a static IP address in the code". If you simply replaced
if (Ethernet.begin(MACaddress) == 0) {
with
if (Ethernet.begin(MACaddress, myIP) == 0) {
the result may be unpredictable, because there is no return value.
Read
EthernetBegin
Returns
The DHCP version of this function, Ethernet.begin(mac), returns an int: 1 on a successful DHCP connection, 0 on failure. The other versions don't return anything.
have you tried one of the examples with fixed IP's?

Resources