Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PubNub Arduino subscribe

Tags:

arduino

pubnub

Hi I am using the example of PubNubsubscriber from the https://github.com/pubnub/arduino I am able to receive messages and as long I receive message everything runs ok, if some time elapses say 20sec without a new message arduino seems to freeze at "waiting for a message (subscribe)" and is unable to receive new incoming messages

Anyone knows why is this happening?

  /*
  PubNub sample subscribe client

  This sample client will subscribe to and handle raw PubNub messages
  (not doing any JSON decoding).  It does so with a randomly generated
  UUID.

  Circuit:
  * Ethernet shield attached to pins 10, 11, 12, 13
  * (Optional.) LED on pin 8 for reception indication.
  * Pin A4 unconnected (noise source for random number generator)

  created 23 October 2012
  by Petr Baudis

  https://github.com/pubnub/pubnub-api/tree/master/arduino
  This code is in the public domain.
  */

  #include <SPI.h>
  #include <Ethernet.h>
  #include <PubNub.h>

// Some Ethernet shields have a MAC address printed on a sticker on the shield;
// fill in that address here, or choose your own at random:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

const int subLedPin = 8;

char pubkey[] = 
char subkey[] = 
char channel[] = "hello_world";
char uuid[] = "xxxxxxxx-xxxx-4444-9999-xxxxxxxxxxxx";

void random_uuid() {
    randomSeed(analogRead(4) + millis() * 1024);
    snprintf(uuid, sizeof(uuid), "%04lx%04lx-%04lx-4444-9999-%04lx%04lx%04lx",
        random(0x10000), random(0x10000), random(0x10000),
        random(0x10000), random(0x10000), random(0x10000));
}

void setup()
{
    pinMode(subLedPin, OUTPUT);
    digitalWrite(subLedPin, LOW);

    Serial.begin(9600);
    Serial.println("Serial set up");

    while (!Ethernet.begin(mac)) {
        Serial.println("Ethernet setup error");
        delay(1000);
    }
    Serial.println("Ethernet set up");

    PubNub.begin(pubkey, subkey);
    random_uuid();
    PubNub.set_uuid(uuid);
    Serial.println("PubNub set up");
}

void flash(int ledPin)
{
    /* Flash LED three times. */
    for (int i = 0; i < 3; i++) {
        digitalWrite(ledPin, HIGH);
        delay(100);
        digitalWrite(ledPin, LOW);
        delay(100);
    }
}

void loop()
{
    Ethernet.maintain();

    PubSubClient *client;

    Serial.println("waiting for a message (subscribe)");
    client = PubNub.subscribe(channel);
    if (!client) {
        Serial.println("subscription error");
        delay(1000);
        return;
    }
    Serial.print("Received: ");
    while (client->wait_for_data()) {
        char c = client->read();
        Serial.print(c);
    }
    client->stop();
    Serial.println();
    flash(subLedPin);

    delay(200);
   }
like image 345
user74627 Avatar asked Nov 29 '25 18:11

user74627


1 Answers

I've spent some time and found out that the issue was in the void PubSubClient::stop() function, while trying to get the timetoken. Now I'm not too sure what exactly is happening here and why it's getting stuck, though it looks like that if you terminate the connection here and skip the timetoken catch, it works like a charm.

This is the original code in PubNub.cpp:

void PubSubClient::stop()
{
    if ((!available() && !connected()) || !json_enabled) {
        PubNub_BASE_CLIENT::stop();
        return;
    }
    /* We are still connected. Read the rest of the stream so that
     * we catch the timetoken. */
    while (wait_for_data()) {
        char ch = read();
        this->_state_input(ch, NULL, 0);
    }
    json_enabled = false;
}

which I've replaced (temporarily) with:

void PubSubClient::stop()
{
    PubNub_BASE_CLIENT::stop();
    return;
}

It's a workaround for now (without the timetoken) and I hope this helps until a proper solution is found.

like image 167
Boris Bachovski Avatar answered Dec 02 '25 03:12

Boris Bachovski



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!