Sprint 7: Particle.publish() released! Let's build a cloud-connected motion detector

Just wanted to mention that I had issues with the spark.publish method because I could not figure out how to convert my data to a char* array. I come from Java and other higher level langauges where String concatenation never was an issue - and then I tried new String().toCharArray() as in the arduino lib and that also did not work (why??).

Great to hear that it will work with String objects soon.

Hi @hansamann

It works like this (swiped from Stackoverflow.com):

String stringOne = "A long integer: ";
stringOne += 123456789;  //concat integer to string
char charBuf[50];  //allocate C string
stringOne.toCharArray(charBuf, 50)   //copy from String memory in stringOne to C string memory charBuff

So toCharArray() is a memory copy routine. The C string always needs to be one location longer than the data you want to hold, since zero (0) is used as special character that means end-of-string.

The .c_str thing is short-hand to allow access to the internal C string storage inside the Arduino String. You could do bad things if you modified this, particularly if you write off the end of it, so it is declared to return const.

Arduino String object are nice and easy to use, but you can find yourself running out of memory at runtime if you allocate and deallocate them a lot.

2 Likes

Hi,
How would I call the API from a webpage? something like this:
https://api.spark.io/v1/events/ -H “Authorization: Bearer {access token}”

thanks!

I’m thinking you might be referring to just a http in a web browser?

For public events:

https://api.spark.io/v1/events/?access_token=xx

For specific events:

https://api.spark.io/v1/events/event_name/?access_token=xxx

For all your own events:

 https://api.spark.io/v1/devices/events/?access_token=xxx

For your own specific events:

 https://api.spark.io/v1/devices/events/event_name/?access_token=xxx
2 Likes

If you want to simply load the data in your browser, that will work in some browsers. However the recommended way to get this into a webpage that you’ve created would be to use the EventSource javascript functionality:

http://www.html5rocks.com/en/tutorials/eventsource/basics/

1 Like

Hi @Dub

Have you looked at this tutorial yet?

Or this one:

3 Likes

thanks Guys!
This is great help for an RF guy! :smile:

1 Like

Dave is there an ETA for the “webhook” support?

My hope was to release it this sprint, but there are implications with regards to making sure we’re not spamming services, and wanting to be sure it’s robust. I would estimate it’ll be ready this next sprint.

Thanks,
David

3 Likes

Ahh… the 80/20 rule. The devil is in the details.

I wrote a Node.JS service a couple of weeks ago to post back to “webhooks” for our product at work that has similar throttling capability. Granted, it helps that the webhook destination is maybe 2 rows over in the data center, so it only takes a week for 200+ million records at 20 concurrent connections max.

We maintain a queue in a bigger database (Redis and/or MSSQL), re-fill the in-NodeJS-memory array queue when 10% of the max size is remaining, and simply cap the max concurrent connections (and can add necessary delays if needed). It’s pretty simple, but the raw power of NodeJS can easily cripple anything by accident. I accidentally filled up our dev server to -5GB free space of Apache logs by using it as a sink for testing purposes. Ooops.

1 Like

@zach it would be great to hear what is the best and recommended (and working) way to consume sse events from non-browser clients. In my case that is node.js - I’ve tried to use eventsource but it seems to not work. I have code up and running in the browser, but due to the access token being publicly in there that is not an option for me.

Thx!
Sven

Perhaps I should have asked here instead?

Hi guys,

Two newbie questions here!

  1. In the opening post, where exactly is this printing stuff to?

    Serial.println(“Motion detected!”);

  2. What does the “*” before the text in the syntax examples below mean?

    SYNTAX
    Spark.publish(const char *eventName, const char *data);
    Spark.publish(String eventName, String data);

    EXAMPLE
    Spark.publish(“temperature”, “19 F”);

Thanks,
R

  1. This will output to Serial or COM port on your machine

  2. * in programming refers to the pointer of the location of eventName :slight_smile:

1 Like

What is not immediately obvious to newcomers to the Spark and to the Arduino is that the Wiring programming language is C (or C++) with a few things bolted on to supposedly make things easier. A good C primer will help you no end. To answer your question try http://www.cs.bu.edu/teaching/c/string/intro/

3 Likes

Thanks!

2 questions from that link:

So, PrintLabel() could have been written in two ways:

void PrintLabel(char the_label[])
{
    printf("Label: %s\n", the_label);
}

OR

void PrintLabel(char *the_label)
{
    printf("Label: %s\n", the_label);
}

In the second case above, there was no need to define the pointer earlier?

Furthermore, the only way to change the contents of an array in C is to make changes to each element in the array.

In other words, we can't do the following:
label = "new value";   /* No! */
label = anotherLabel;  /* Wrong! */

^ Does this hold true even for wiring? I can’t ‘overwrite’ new text into an existing string?

Thanks!!
R

(Maybe the moderators want to split the last few posts into a “Newbie’s guide to pointers” type thread?)

2 Likes

At the underlying machine code level the usual way to refer to an array is to give the memory address of the first element in the array. C works at a level not far removed from machine code. But whatever language you use, underlying it all, you are right: to change an array you do it one element at a time. Some languages help you more than others but at least in C it is possible to work out exactly what is going on.

There are attempts to make string handling in Wiring easier and more intuitive using C++ classes such as the (capital-S) String class. Now, I don’t think they make anything easier that way, but that’s me, others may disagree. You might want to give it a try. http://docs.spark.io/firmware/#other-functions-string-class

Q1: Equivalent.
Q2: The parameters to a function are declared as local variables to the function. Each of your two functions compile down to the same code. Each declare the_label as a pointer to char. char *p and char p[] are equivalent.
Q3: strcpy(a, "somestring"); sets (=overwrites) the contents of array a [=sets the contents of a and subsequent memory locations] ending with the implied NUL char ‘\0’ at the end of “somestring”.

You can do the following:

char a[22];
char *s;

s = "new value";
/* set the contents of character pointer s to the address of the beginning of this constant string 
(the compiler puts the constant string in a special data area for you and sets label to point to it)
- nothing is changed, nothing is copied - a pointer is set */

s = "another string"; // s now points at another constant string
// and you can no longer reference the former string, although it is still there
// once again no string is changed or copied, only a pointer is set

strcpy( a, s); 
/* copy the char at address s to address a, advancing one char at a time, until nul '\0' is encountered
This time data is copied, the addresses are not changed */

s = a; // set the contents of character pointer s to the address of the 1st element of a 
a[4] = 'x' ; //note single quotes for char double for string - the 5th element of char array a is set to 'x'
// note that in changing a[4] we have also changed s[4] - they're the same. And s[4] is valid syntax!
4 Likes

Hi Zach,
Thanks for a great tut. but the link to see the code is not working, can you post it the code thanks
Best
Meth

If you mean the code to the gist; The actual code is directly below it. If not, then could you please describe what code you’re looking for?