Get Device Name returning garbage

I think the String concatenation was f’ing up your data…

try this:

//char deviceName[32] = "unknown";
String deviceName = "unknown";

void setup()
{
  Serial.begin(9600);
  Particle.subscribe("particle/device/name", getName, MY_DEVICES);
  Particle.variable("DeviceName", deviceName);
}

void loop()
{
}

void getName(const char *event, const char *data)
{
  Serial.printlnf("received  %s: %s", event, data);
  //strcpy(deviceName, data); // also works with char array
  deviceName = data;
}

If you go back and read the entire thread you will see I have already tried your suggestion and it did not fix the issue.
A 20 second wait after connecting to the cloud does fix the issue.
Its nothing to do with string handling. Its clearly a race condition with the cloud data.

If you read threads on other things like getting your external IP you would find the same thing, you cannot read values for these things as soon as Particle.connected is true but you can speed things up a bit by running Particle.process() before trying…

No, I mean I could duplicate your issue even with a 20 second startup delay.

//char myName[32] = "unknown";
String myName = "unknown";

void setup()
{
  pinMode(D7, OUTPUT);
  Serial.begin(9600);
  Particle.subscribe("particle/device/name", getName, MY_DEVICES);
  Particle.variable("DeviceName", myName);
  uint32_t now = millis();
  while (millis() - now < 20000)
    Particle.process();
  digitalWrite(D7, HIGH);
}

void loop()
{

}

void getName(const char *topic, const char *data) {
  Particle.publish("received " + String(topic) + ": " + String(data));  //<<<<<< . NOTE THIS SMALL CHANGE
  //Serial.printlnf("received %s: %s", topic, data);
  myName=String(data);
}

/*void getName(const char *event, const char *data)
{
  //strcpy(myName, data); // works with char array
  myName = data;
}*/


with this happening:

event: particle/device/name
data: {"data":"testing","ttl":60,"published_at":"2017-11-02T10:02:01.867Z","coreid":"api"}

event: received particle/device/name: testing
data: {"data":"null","ttl":60,"published_at":"2017-11-02T10:02:01.885Z","coreid":"280041000d47353136383631"}

note the null in the data returned on the publish. and this I see in my Variable:

��W.���Ӓ��Y��n5��肷�3.����Þĩ�|xaS0���%=��Z)���tL�>��E����'�'�P��_n��~'֨� v�ˣ�����+�O&����Q��H(pZ�WF�ԟqh�c�U�RY�;$d`�W�\���

Removing your string handling (as with the code I posted earlier)… it then works with or without the delay.

it is strange, maybe some other folks can test the code posted here…

1 Like

Yet I tried it with your code for the string handling and it failed without the delay.

Just once I saw it return the same data as another event my device subscribes to, which makes it look like the event handler can trigger before the buffer has been filled with the correct data. I believe there is only one buffer for all events?
By the way, you do know you are not supposed to try to Publish inside an event handler for a subscription? Saw that in another thread somewhere, and its due to buffer re-use.
FFS it shouldn’t be this hard to make such a simple request work.
I have another idea to try …

maybe two

Make sure that your Particle.subscribe() is at the very top of your setup() function, well ahead of anything like your first call to publish().

You want to make sure you are registering the cloud services before anything else. I’ve seen unexpected things like what you are experiencing… if I wait too long to do that cloud setup.

how many subscribe() functions do you have? Another method would be to create only one handler for all of your responses to cloud events.

you can see by the code I posted, without anything else interfering, it works as expected.

I have just two subscribes, and they are at the start. I do have a lot of variables and functions registered, which is slowing things down . I can get rid of most of them, as they were only needed in the early stages of the project.

Going back to this method (with a small extra delay) - I’m not keen on relying on absolute time delays.

void reqName(void)
{

 if (waitFor(Particle.connected, 30000))
 {
    while(Particle.syncTimePending())
    {
      Particle.process();
    }
    delay(1000);  //small extra delay
    Particle.publish("particle/device/name");
 }
}

I still think it should be up to the system firmware to ensure valid data for a documented system call, or at least provide a flag if valid data is not available.

For me it is 100% of the time I get garbage. I am using the Redbear DUO if that makes a difference, but at this point I can not get the device name.

To be fair, I just moved away from device names completely and work with the Device ID instead. A very long number that doesn’t make it easy to analyze data manually, but at least it’s reliable…

If you are using Web IDE can you post a snapshot-link?
Otherwise post your full code?

For me it works 100% of the time - even with Duo. So it’s not the system as such :wink: