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.
Related
Simple Ethernet communication between two Arduino boards. I used two Arduino UNO boards, Two Arduino Ethernet Shields.
Here is my Server Code
//Server
#include <SPI.h>
#include <Ethernet.h>
// network configuration. gateway and subnet are optional.
// the media access control (ethernet hardware) address for the shield:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//the IP address for the shield:
byte ip[] = { 192,168,1,180 };
// the router's gateway address:
byte gateway[] = { 192, 168, 1, 1 };
// the subnet:
byte subnet[] = { 255, 255, 255, 0 };
EthernetServer server = EthernetServer(10001);
void setup()
{
// initialize the ethernet device
Ethernet.begin(mac, ip, gateway, subnet);
// start listening for clients
server.begin();
}
void loop()
{
// if an incoming client connects, there will be bytes available to read:
EthernetClient client = server.available();
if (client == true) {
// read bytes from the incoming client and write them back
// to any clients connected to the server:
server.write(client.read());
}
}
Here is my Client Code
//Client
#include <Ethernet.h>
#include <SPI.h>
byte mac[] = {0xDE,0xAD,0xBE,0xEF,0xFE,0xEC};
IPAddress ip(192,168,1,177);
IPAddress server(192,168,1,180);
EthernetClient client(10001);
void setup()
{
Ethernet.begin(mac, ip);
Serial.begin(9600);
delay(1000);
Serial.println("connecting...");
if (client.connect(server, 10001)) {
Serial.println("connected");
client.println("GET /search?q=arduino HTTP/1.0");
client.println();
} else {
Serial.println("connection failed");
}
}
void loop()
{
if (client.available()) {
char c = client.read();
Serial.print(c);
}
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
for(;;)
;
}
}
I input those two codes to two Arduino boards. Wiring and other connection are correct and reliable.
But I got this output from client serial monitor
connecting...
connection failed
disconnecting.
According to my view, error may happen in client code. Can you help me to find the error?
I'm trying to complete my brewing system with Arduino, Raspberry, mqtt, MySql, Php.
I want to switch from sending data via serial port to ethernet+MQTT.
When I try to publish-subscribe with PubSubClient everything goes well. But whenever I try to put the DallasTemperature begin() function it can't connect anymore to the broker.
As soon as I remove the instruction sensors.begin(); it restarts and works perfectly.
Any of you knows why the hell is acting like this?
Here the code:
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SPI.h>
#include <PubSubClient.h>
#include <Ethernet.h>
#define ONE_WIRE_BUS 10
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature Sensors(&oneWire);
// Pins
const int photocellPin = 1; // the cell and 10K pulldown are connected to a1
// Variables
String lightC;
unsigned long time;
char message_buffer[100];
// Network Settings
// MAC address of ethernet shield
// Look for it on a sticket at the bottom of the shield.
// Old Arduino Ethernet Shields or clones may not have a dedicated MAC address. Set any hex values here.
byte MAC_ADDRESS[] = { 0xFE, 0xED, 0xDE, 0xAD, 0xBE, 0xED };
// IP address of MQTT server
byte MQTT_SERVER[] = { 192, 168, 2, 46 }; // 10, 192, 191, 77 { 192, 168, 1, 115 };
// Handles messages arrived on subscribed topic(s)
void callback(char* topic, byte* payload, unsigned int length)
{
Serial.print("Messaggio ricevuto [");
Serial.print(topic);
Serial.print("]");
for (int i = 0; i < length; i++) {
char receivedChar = (char)payload[i];
Serial.print(receivedChar);
}
Serial.println();
}
EthernetClient ethClient;
PubSubClient client(MQTT_SERVER, 1883, callback, ethClient);
IPAddress ip(192, 168, 2, 177);
void setup()
{
// Initilize serial link for debugging
Serial.begin(9600);
Ethernet.begin(MAC_ADDRESS, ip);
delay(2000);
// initialize the digital pin's as an output.
Serial.println("connected...");
Sensors.begin();
Serial.println("initialized..."); // Just for checking
}
void loop()
{
if (!client.connected()) {
reconnect();
}
lightC = dtostrf(analogRead(photocellPin), 5, 2, message_buffer); // TMP36 sensor calibration
Serial.println(lightC);
delay(2000);
// Publish sensor reading every X milliseconds
if (millis() > (time + 60000)) {
time = millis();
client.publish("fromarduino", (char*)lightC.c_str());
}
// MQTT client loop processing
client.loop();
}
void reconnect()
{
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("mb-arduino")) {
Serial.println("MQTT connected");
client.publish("fromarduino/alive", "I'm alive!");
client.subscribe("toarduino");
}
else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
It always returns error rc=-2.
I'm trying to send sensor data via UDP. At the moment I'm struggling with the "packing" of the UDP packets. It says "incomingData" is not declared when I try to send it.
I would appreciate any kind of advice.
Code below.
Thank you :)
//Version 1.012
//necessary libraries
#include <SPI.h>
#include <Ethernet2.h>
#include <EthernetUdp2.h>
//Pin settings
#define CTD 19
//Network Settings
byte mac[] = { 0x90, 0xA2, 0xDA, 0x10, 0xEC, 0xAB }; //set MAC Address Ethernet Shield (Backside)
byte ip[] = { XXX, XXX, X, X }; //set IP-Address
byte gateway[] = { XXX, XXX, X, X }; //set Gateway
byte subnet[] = { 255, 255, 255, 1 }; //set Subnetmask
//local UDP port to listen on
unsigned int localPort = 4000;
//Recipient IP
IPAddress RecipientIP(127, 0, 0, 1);
//Recipient UDP port
unsigned int RecipientPort = 4444;
//Buffer for sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
//EthernetUDP instance
EthernetUDP Udp;
void setup()
{
//Start Ethernet
Ethernet.begin(mac, ip);
//Start UDP
Udp.begin(localPort);
//for debug only
Serial.begin(9600);
//Serial baud rate for CTD
Serial1.begin(1200);
//Version 1.012
Serial.print("Version 1.012");
//CTD
pinMode(CTD, INPUT);
}
void loop()
{
//If CTD is sending
if (Serial1.available())
{
//read incoming data
int incomingData = Serial1.read();
//for debug only
Serial.print("Data: ");
Serial.println(incomingData, BIN);
}
//Send UDP packets
int packetSize = Udp.parsePacket();
if (packetSize) {
// read the packet into packetBufffer
Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
// send to the IP address and port
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(incomingData);
Udp.endPacket();
}
}
In your code you have declared incomingData as int inside void loop () function inside if (Serial1.available()) .
But if the above if loop fails the incomingData will not be declared and say packetsize is greater than zero ( packet available) then if (packetSize) segment will be executed.Thus incomingData is not declared but it is used .That's why you get the error you stated.
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('.');
}
}
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);