SparkFun Forums 

Where electronics enthusiasts find answers.

Everything pertaining to the data.sparkfun.com service, the phant project which powers it, and user projects which talk to the service.
By geo_leeman
#175339
Hello all,

I'm trying to post some magnetometer data on data.sparkfun with the Yun and running into an issue:

I can get the example sketch https://learn.sparkfun.com/tutorials/pu ... arduino-yn of posting data with the Yun running just fine, so I know that the Yun can see the internet with no issues. When I try to post data from my sketch (below), I get pages and pages of garbled response. If I comment out the section of code that shows the response I can grab the curl command that is generated. That works fine when run from the command line on my computer, so the syntax isn’t wrong either. All baud rates are set correctly as well. Any ideas?

curl command generated on Arduino:
curl --header "Phant-Private-Key: XRR8oNoxjdH4W1nB84qn" --data "MagNorth=-29062.67" --data "MagEast=34957.33" --data "MagUp=76166.67" http://data.sparkfun.com/input/WGGbqQqxZRSKmXLEnKoL
Code: Select all
#include <Wire.h>
#include <Process.h>

// Constants for Magnetometer
#define MAG_ADDR  0x0E //7-bit address for the MAG3110, doesn't change
#define NUMSAMPLES 5
#define NUMAVERAGES 5

// Phant Configuration 

//Public URL: https://data.sparkfun.com/streams/WGGbqQqxZRSKmXLEnKoL


// URL to phant server 
String phantURL = "http://data.sparkfun.com/input/";
// Public key:
String publicKey = "WGGbqQqxZRSKmXLEnKoL";
// Private key
String privateKey = "XRR8oNoxjdH4W1nB84qn";
// Data Fields to Stream
const int NUM_FIELDS = 3;
// Set Field Names
String fieldName[NUM_FIELDS] = {"MagNorth", "MagEast", "MagUp"};
// Array to store data for each field
String fieldData[NUM_FIELDS];

float avg_x;
float avg_y;
float avg_z;
float lta_x;
float lta_y;
float lta_z;

uint8_t i;
uint8_t j;

void setup(void)
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(115200);  // start serial for output
  config();            // turn the MAG3110 on
}

void loop(void)
{

  lta_x = 0;
  lta_y = 0;
  lta_z = 0;
  
  for (i=0; i<NUMAVERAGES; i++) {
    avg_x = 0;
    avg_y = 0;
    avg_z = 0;
    for (j=0; j<NUMSAMPLES; j++) {
      avg_x += read_x();
      avg_y += read_y();
      avg_z += read_z();
    }
    avg_x /= NUMSAMPLES;
    avg_y /= NUMSAMPLES;
    avg_z /= NUMSAMPLES;
    
    lta_x += avg_x;
    lta_y += avg_y;
    lta_z += avg_z;
  }
  
  lta_x /= NUMAVERAGES;
  lta_y /= NUMAVERAGES;
  lta_z /= NUMAVERAGES;
  
  lta_x /= 0.03;
  lta_y /= 0.03;
  lta_z /= 0.03;
  
  fieldData[0] = String(lta_y);
  fieldData[1] = String(lta_x);
  fieldData[2] = String(lta_z);
  
  // Post Data
  Serial.println("Posting Data!");
  Serial.println(fieldData[0]);
  Serial.println(fieldData[1]);
  Serial.println(fieldData[2]);
  
  delay(1000);
  postData(); // the postData() function does all the work, 
                // see below.
  delay(5000);
}

void config(void)
{
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x11);              // cntrl register2
  Wire.write(0x80);              // write 0x80, enable auto resets
  Wire.endTransmission();       // stop transmitting
  
  delay(15);
  
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x10);              // cntrl register1
  Wire.write(0x19);                 // turn on over sampling and make active mode
  Wire.endTransmission();       // stop transmitting
}

int read_x(void)
{
  int xl, xh;  //define the MSB and LSB
  
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x01);              // x MSB reg
  Wire.endTransmission();       // stop transmitting
 
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
  while(Wire.available())    // slave may write less than requested
  { 
    xh = Wire.read(); // read the byte
  }
  
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x02);              // x LSB reg
  Wire.endTransmission();       // stop transmitting
 
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
  while(Wire.available())    // slave may write less than requested
  { 
    xl = Wire.read(); // read the byte
  }
  
  int xout = (xl|(xh << 8)); //concatenate the MSB and LSB
  return xout;
}

int read_y(void)
{
  int yl, yh;  //define the MSB and LSB
  
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x03);              // y MSB reg
  Wire.endTransmission();       // stop transmitting
 
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
  while(Wire.available())    // slave may write less than requested
  { 
    yh = Wire.read(); // read the byte
  }
  
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x04);              // y LSB reg
  Wire.endTransmission();       // stop transmitting
 
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
  while(Wire.available())    // slave may write less than requested
  { 
    yl = Wire.read(); // read the byte
  }
  
  int yout = (yl|(yh << 8)); //concatenate the MSB and LSB
  return yout;
}

int read_z(void)
{
  int zl, zh;  //define the MSB and LSB
  
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x05);              // z MSB reg
  Wire.endTransmission();       // stop transmitting
 
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
  while(Wire.available())    // slave may write less than requested
  { 
    zh = Wire.read(); // read the byte
  }
  
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x06);              // z LSB reg
  Wire.endTransmission();       // stop transmitting
 
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
  while(Wire.available())    // slave may write less than requested
  { 
    zl = Wire.read(); // read the byte
  }
  
  int zout = (zl|(zh << 8)); //concatenate the MSB and LSB
  return zout;
}

void postData()
{
  Process phant; // Used to send command to Shell, and view response
  String curlCmd; // Where we'll put our curl command
  String curlData[NUM_FIELDS]; // temp variables to store curl data

  // Construct curl data fields
  // Should look like: --data "fieldName=fieldData"
  for (int i=0; i<NUM_FIELDS; i++)
  {
    curlData[i] = "--data \"" + fieldName[i] + "=" + fieldData[i] + "\" ";
  }

  // Construct the curl command:
  curlCmd = "curl ";
  curlCmd += "--header "; // Put our private key in the header.
  curlCmd += "\"Phant-Private-Key: "; // Tells our server the key is coming
  curlCmd += privateKey; 
  curlCmd += "\" "; // Enclose the entire header with quotes.
  for (int i=0; i<NUM_FIELDS; i++)
    curlCmd += curlData[i]; // Add our data fields to the command
  curlCmd += phantURL + publicKey; // Add the server URL, including public key

  // Send the curl command:
  Serial.print("Sending command: ");
  Serial.println(curlCmd); // Print command for debug
  phant.runShellCommand(curlCmd); // Send command through Shell

  // Read out the response:
  Serial.print("Response: ");
  // Use the phant process to read in any response from Linux:
  while (phant.available())
  {
    char c = phant.read();
    Serial.write(c);
  }
}

By geo_leeman
#175355
Valen wrote:I think your private key was supposed to stay private. Unless you don't care if others polute the data storage in the future.
Yep... I plan on killing this stream and re-making it after the issue is cleared up. Just wanted to make it fully reproducible.
By Valen
#175357
I don't have an Arduino Yun or a network shield for my Arduino Uno to test this so I won't be much help. Definitely do not have the magnetic sensor either. But I figure it might help others if they could also see the random garbage text response that you get. (if possible characters shown in normal text and in hex format) Can you post the shell output also? Is it really random, or can you reproduce the same stream content every time. And it just looks sequence of random characters because it is so much.

Just a wild guess here. Could it be that you are receiving the encrypted stream from the https- protocol, instead of the http protocol that should be plaintext.
By geo_leeman
#175362
Valen wrote: Just a wild guess here. Could it be that you are receiving the encrypted stream from the https- protocol, instead of the http protocol that should be plaintext.
I don't think that's the issue, since running on the terminal of a normal computer returns a reasonable response. I'll post the full text dump tonight.
By Valen
#175363
I noticed your code does not contain the Bridge.begin command in Setup that the SparkFun example has. Maybe your Yun has a brain-dysfunction because of it.
Code: Select all
...void setup() 
{
  Bridge.begin();
  Serial.begin(115200);

..
By geo_leeman
#175377
That's it! I did a diff on the code and the example awhile back when developing it, but somehow that line got deleted when editing. I guess it just took a fresh set of eyes! :dance:

Thank you!