LSM303 data from I2C [SOLVED]

peekay123,
Thanks!

LSM303 was detected
LSM303 was detected
LSM303 was detected
LSM303 was detected
LSM303 was detected

Dup, I should really re-read my code before posting! Here is the correct code that would also print the data:

include "application.h"
include "LSM303.h"
LSM303 compass;

char report[80];
bool error;

void setup()
{

	Serial.begin(9600);
	Wire.begin();
	delay(3000);				// Delay to allow for starting up Serial console
	error = compass.init()		// Returns "true" if device found
	compass.enableDefault();
}

void loop()
{
	if (error == false) {		// Returns "false" if device NOT found
		Serial.println("LSM303 was NOT detected");
	}
	else {
		Serial.println("Reading...");
		compass.read();

		sprintf(report, sizeof(report), "A: %6d %6d %6d M: %6d %6d %6d",
		compass.a.x, compass.a.y, compass.a.z,
		compass.m.x, compass.m.y, compass.m.z);
		Serial.println(report);
	}

	delay(1000);
}

Have fun!

thanks!
I get this…pretty cool stuff

Reading…
A: 215 471 -16010 M: -2086 -2548 2199

next step is to get this stuff into a spreadsheet…thanks again!

Dup, check out this topic on logging to a Google SpreadSheet! :smile:

1 Like

peekay123,
Thanks!!
Dup

@peekay123

Hi peekay123,
I am having difficulty fetching the data into the spreadsheet. I have succeeded in bringing in single data such as temp along with timestamp however the accelerometer has multiple data points A: 215 471 -16010 M: -2086 -2548 2199 and I can’t seem to figure out how to JSON parse! :frowning:

This is what I have:

sprintf(resultstr, "{“report:A: %6d %6d %6d M: %6d %6d %6d}”); // format your data as JSON, don’t forget to escape the double quotes

Any idea?
Thanks for the help!

Dup, the data that you are producing needs to be in JSON format similar to the example on the logging topic:

sprintf(resultstr, "{\"data1\":%d,\"data2\":%d}", data1, data2);

the result of doing a GET from the spreadsheet will look like this:

"result": "{\"data1\":23,\"data2\":26,}",

The JSON structure here shows a string object called “results”. This string can be parsed into parts by using the “” delimiter to get names (data1, data2) and values (23, 26). This can be parsed by the google spreadsheet using (from the example):

  var p = JSON.parse(result); // parse the JSON you created
  var d = new Date(); // time stamps are always good when taking readings
  sheet.appendRow([d, p.data1, p.data2]); // append the date, data1, data2 to the sheet

So your code should read something like this:

sprintf (resultstr, “{“Ax”:%6d,“Ay”:%6d,“Az”:%6d,“Mx”:%6d,“My”:%6d,“Mx”:%6d}”, ax, ay, az, mx, my, mz);

Which will result in this JSON output from the Spark Cloud (where 1234 is the actual value of the variables):

“result”: “{“Ax”:1233,“Ay”:1234,“Az”:1234,“Mx”:1234,“My”:1234,“Mx”:1234}”

Then, in the spreadsheet, you parse that out like this:

sheet.appendRow([d, p.Ax, p.Ay, p.Az, p.Mx, p.My, p.Mz]); // append the date and data to the sheet

Give that a shot and let me know how it goes. :smile:

2 Likes

Thanks peekay123!
I got it going!!
3/27/2014 13:23:54 360 290 -15901 1443 -97 1114
3/27/2014 13:26:02 333 118 -15905 1349 317 1001
3/27/2014 13:29:51 466 75 -15962 1465 139 1017
3/27/2014 13:30:50 448 73 -15941 1486 150 1022
3/27/2014 13:32:04 419 73 -15934 1480 145 1030
3/27/2014 13:32:05 419 73 -15934 1480 145 1030

For some reason I had to create a new spreadsheet and not update an existing. Now I can examine the stability of the component while sitting still along with other tests

I learned something this morning, due to the crazy snow storm in NB, my kids are on the Xbox playing Call of Duty and I think it is affecting my core wifi operation! I had issues flashing, and it appears to affect the fetching into the spreadsheet.

Thanks again!

2 Likes

Glad you guys got things working! :slight_smile:

Now that I have things working, I can see real-time data via serial USB :slight_smile: The sensor can generate data at high speeds which I would like to store and analyse.
Can I store the data on the core then “GET” or “PUBLISH” so I can get a snapshot of the data? I.e. every 5 mins the core collects data then publishes all of the collected data
Thanks!

Dup, there are a couple of challenges with this. First, Spark.publish() is limited to a string of 63 characters per call. On top of that, there is a limit on how many publish events you can have per minute. I believe using publish is not feasible here.

The second challenge is the amount of available RAM. Storing 5 minutes worth of data (assume 40 bytes) at 1 second intervals would be 300 * 40 = 1200 bytes which I suspect will push your code over the available limit.

Another way is to use the microSD library, store you data on the SD and then “POST” the data using TCPClient or “GET” the data using TCPServer. :smile:

1 Like

thanks peekay123!
It takes me time to respond but I need to educate myself everytime before I answer :smile:
So I should be able to “POST” the data to i.e. Dropbox using TCP Client, then I can use the data from there, right? Is there a limit to size of the “POST”?
Thanks!

1 Like

Dup, you will need to keep your POSTs relatively small, again due to RAM constraints depending on your program’s overall memory requirements. As for posting to a site, as long as it does not require HTTPS then you should be ok, subject to their posting policies (posts per minute, data size, etc). There is a topic on posting data to a Google spreadsheet that you may want to look at as well:

Hi peekay123,
I have things working with google and now i am trying to POST to dropbox. I am able to curl a request and now I want to perform an HTTP POST to Dropbox via client.print. I know the URL structure, method and parameters but I am having difficulty writing the code. I used the Xively example in the attempt to figure it out but it is not clear to me.

DOES this=
curl https://api.dropbox.com/1/datastores/put_delta -d handle= -d rev=1 -d changes="[[“I”, “tasks”, “myrecord”, {“taskname”: “do laundry”, “completed”: false}]]" -H "Authorization: Bearer "

EQUAL this=
/Serial.println(“Connecting to server…”);
if (client.connect(“api.dropbox.com/1/datastores”, 8081))

// Connection succesful, update table
client.print("{");
client.print(" “method” : “put_delta”,");
client.print(" “params” : {},");
client.print(" “handle” : “<DATASTORE-HANDLE>”,");
client.print(" “rev” : “<rev>”,");
client.print(" “changes” : “[[“I”, “tasks”, “myrecord”, {“taskname”: “do laundry”, “completed”: false}]]”);
client.print(" “Authorization” : “<YOUR-ACCESS-TOKEN>”);
client.print("}");
client.println();

thanks!

1 Like

Hi @Dup

I think that Dropbox requires SSL/TLS (i.e. https) and does not allow basic auth. Does your curl request work if you change https to http?

I would love to be wrong, but I think you may need to wait for the Spark team to finish the web hooks feature they are working on.

Hi bko,
Dropbox uses HTTPS just like Xively which I was able to connect to. If I could figure out how to write the code, then I could test it. As I understand it, HTTP has URL structure, Method, Parameters and Body but from the curl command above, I can’t seem to figure out how to write the code
Thanks!

Hi @Dup

The Spark core is not capable of using SSL/TLS https today. If you were talking directly to Xively from a core, you must be using plain http, perhaps with authorization (username and password called basic auth or the Authorization: Bearer token) but not encrypted SSL/TLS.

Since Xively is an IoT company they say:

Notes

While it is possible to communicate with Xively using HTTP, this method is not secure and it is not recommended. It remains a part of the service as an element of legacy support. It is recommended to use ‘HTTPS’ in all API requests: https://api.xively.com.

Dropbox is not an IoT company and requires SSL/TLS encrypted connections in my experience.

1 Like

As @bko mentioned, we don’t have HTTPS support. But even besides that, I think you need a few changes. Maybe something like:

//Serial.println("Connecting to server...");
if (client.connect("api.dropbox.com", 8081)) {
    // Connection succesful, update table
    client.println("POST /1/datastores/put_delta HTTP/1.0");
    client.println("Authorization: Bearer");
    client.println(""); // end of headers, start of data
    client.print("{");
    client.print("'handle': '',");
    client.print("'rev': '1',");
    client.print("'changes': '[['I', 'tasks', 'myrecord', {'taskname': 'do laundry', 'completed': false}]]");
    client.println("}");
}

The Dropbox API docs also mention a ‘nonce’ parameter for the datastores/put_delta call, but I’m not familiar with their API, so I have to assume you know where to get that.

In any case, the above would be closer to the curl command you have. I specified the ‘POST’ HTTP method because that’s what the Dropbox API docs say is needed. The ‘Authorization: Bearer’ header has to be moved up above the regular data. And lastly, I changed the JSON to use single quotes around strings to eliminate all the quote escaping you were doing before, and make things more readable.

Thanks guys!
I will process this stuff and educate myself some more! :slight_smile: Is there another way to get the data onto Dropbox securely i.e. instead of POST perhaps expose the data then GET from Dropbox? My plan is to use an SD card with my core to store the data then somehow get it to Dropbox or something similar
Thanks!

Coming soon from the Spark team will be a “web hooks” feature that lets you register something for the :spark: cloud to do securely to or from another host on the internet, based on a core event or variable or function.

It might be something like, when the cloud gets a Spark.publish() event from your core, you have set it up to do an HTTPS POST to dropbox with the publish data.

You can do this today with your own host on the internet or a few services but having it in the Spark cloud is a major advantage since the connection to and from the cloud is encrypted and private already.

2 Likes