Yun + MySQL + writing 8 values via php?

Almost done. I popped in a while ago to ask about writing 2 values to a sql database and was helped immensely, so I am hoping to get one more bit of help.

I am currently setting up remote sensor units that will pull the data, readings from a dht11 and 5 vernier sensor probes.

The code sets up variables that hold the slope and intercepts for linear calibrations, gets the reading from the analog port and calculates the calibrated measurement.

The code then compiles it (to send to SD for backup(not implemented yet...)) and sends the individual values to the linux side of the yun.

Here is the code.

#include <FileIO.h>
#include <DHT.h>
#include <Process.h>
#include <Console.h>
#include <math.h>

#define DHTPIN 4   
#define DHTTYPE DHT11 
DHT dht(DHTPIN, DHTTYPE);

int sensor1Port = A0; //Thermometer
int sensor2Port = A1;
int sensor3Port = A2;
int sensor4Port = A3;
int sensor5Port = A4;

int sensor1Value = 0;
int sensor2Value = 0;
int sensor3Value = 0;
int sensor4Value = 0;
int sensor5Value = 0;


void setup() {
   Bridge.begin();  // Initialize Bridge
   FileSystem.begin(); //Initialize FileSystem
   Console.begin(); 
      Console.println("You're connected to the Console!!!!");
      Serial.begin(115200);

// initialize digital pin 13 as an output (light to show start of process).
     pinMode(13, OUTPUT);
}

void loop() {
    
// Sensor Slope Intercepts
  
  int slopeSensor1 = 5;
  int interceptSensor1 = 1;
  int slopeSensor2 = 5;
  int interceptSensor2 = 1;
  int slopeSensor3 = 5;
  int interceptSensor3 = 1;
  int slopeSensor4 = 5;
  int interceptSensor4 = 1;
  int slopeSensor5 = 5;
  int interceptSensor5 = 1;
  
//Get the date and time  
  String dataString;
  dataString += getTimeStamp();
  String datestring = dataString;
  
  Console.println(dataString);
  
//DHT11 readings
 int h = dht.readHumidity();
 int t = dht.readTemperature();
  
//Light to show start of process  
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level) to show start

//Start Calculations

  int data; //reading from the A/D converter (10-bit)
  float Temp; //the print below does the division first to avoid overflows
  data=analogRead(sensor1Port);       // read count from the A/D converter 
  sensor1Value=Thermistor(data);       // and  convert it to CelsiusSerial.print(Time/1000); //display in seconds, not milliseconds                       


//Passing raw values to calculating process
data = analogRead(sensor2Port);
sensor2Value = sensorValueCalculate(slopeSensor2, interceptSensor2, data); 
data = analogRead(sensor3Port);
sensor2Value = sensorValueCalculate(slopeSensor3, interceptSensor3, data);
data = analogRead(sensor4Port);
sensor2Value = sensorValueCalculate(slopeSensor4, interceptSensor4, data);
data = analogRead(sensor5Port);
sensor2Value = sensorValueCalculate(slopeSensor5, interceptSensor5, data);


//Create Datastring to show in console and then write to CSV
dataString += ("," + String(t) + "," + String(h) + "," + String(sensor1Value) + "," + String(sensor2Value) + "," + String(sensor3Value) + "," + String(sensor4Value) + "," + String(sensor5Value));

Console.println(dataString);

Console.println("Sending data to SQL database");
// Send data to MySQL database  
  Process p;              
   p.begin("/mnt/sda1/db.php");
   p.addParameter(String(datestring));   
   p.addParameter(String(t));
   p.addParameter(String(h)); 
   p.addParameter(String(sensor1Value));
   p.addParameter(String(sensor2Value)); 
   p.addParameter(String(sensor3Value));
   p.addParameter(String(sensor4Value)); 
   p.addParameter(String(sensor5Value));
   p.run();

Console.println("Finished sending data to SQL database");

  digitalWrite(13, LOW);   // turn the LED on (HIGH is the voltage level) to show start
delay(500); //Wait for one hour to run again
}

// This function return a string with the time stamp
String getTimeStamp() {
  String result;
  Process time;
  // date is a command line utility to get the date and the time 
  // in different formats depending on the additional parameter 
  time.begin("date");
  time.addParameter("+%D-%T");  // parameters: D for the complete date mm/dd/yy
                                //             T for the time hh:mm:ss    
  time.run();  // run the command

  // read the output of the command
  while(time.available()>0) {
    char c = time.read();
    if(c != '\n')
      result += c;
  }

  return result;
}

//This function will calculate the calibrated Sensor Value
int sensorValueCalculate(int slope, int intercept, int RawData) {
  Console.println("Calculating");
  int CalibratedReading = intercept + RawData * slope;
  Console.println(CalibratedReading);
  return CalibratedReading;  
}

float Thermistor(int Raw) //This function calculates temperature from ADC count
{
 long Resistance; 
 float Resistor = 15000; //fixed resistor
  float Temp;  // Dual-Purpose variable to save space.
  Resistance=( Resistor*Raw /(1024-Raw)); 
  Temp = log(Resistance); // Saving the Log(resistance) so not to calculate  it 4 times later
  Temp = 1 / (0.00102119 + (0.000222468 * Temp) + (0.000000133342 * Temp * Temp * Temp));
  Temp = Temp - 273.15;  // Convert Kelvin to Celsius                      
  return Temp;                                      // Return the Temperature
}

This is the db.php file that runs.

#!/usr/bin/php-cli
<?php
$datetimestamp = $argv[1];
$temperature = $argv[2]; 
$humidity = $argv[3];
$sensor1Value = $argv[4];
$sensor2Value = $argv[5];
$sensor3Value = $argv[6];
$sensor4Value = $argv[7];
$sensor5Value = $argv[8];
$DBServer = '192.168.0.99'; 
$DBUser   = 'root';
$DBPass   = 'password';
$DBName   = 'sensors';  
$conn = new mysqli($DBServer, $DBUser, $DBPass, $DBName);
// check connection
if ($conn->connect_error) {
  trigger_error('Database connection failed: '  . $conn->connect_error, E_USER_ERROR);
}
$sql="INSERT INTO sensor_data (datetimestamp, Ambienttemp, Ambienthumidity, Sensor1value, Sensor2value, Sensor3value, Sensor4value, Sensor5value) VALUES ($datetimestamp, $temperature, $humidity, $sensor1Value, $sensor2Value, $sensor3Value, $sensor4Value, $sensor5Value)";
if($conn->query($sql) === false) {
  trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR);
} 
?>

as with last time, sshing into the yun and running this from the prompt puts data into the database.

/mnt/sda1/db.php  80 40 34 34 34 34 34 34

Running the arduino program above gives all the indications that it is passing the data but nothing ends up in the database.

I would imagine that like last time, I have some basic error that is killing it.

Thoughts?

Your code is OK, but could be fine tune.

  1. Database schema:

Create table with AUTO_INCREMENT and (AUTO) TIMESTAMP as well as PRIMARY KEY.

CREATE TABLE temperatura_new (
id INT NOT NULL AUTO_INCREMENT,
tempdegree VARCHAR(20),
insert_date TIMESTAMP,
PRIMARY KEY (id)
);

Now we are no longer need getTimeStamp function as well as one parameter datestring.

http://forum.arduino.cc/index.php?topic=214431.msg1574406#msg1574406

  1. Move all business logic (sensorValueCalculate, Thermistor) from ATmega32u4 to AR9331's php side ( application layer). Offload ATmega32u4 to dummy data collector.

  2. If you mysql server is remote, normally it hosted at box much powerful than AR9331. You could scale business logic up to database layer (trigger).

Thank you for the suggestions sonnyyu (you have saved me before), but I still have a bug somewhere.

When I run the arduino code above, it goes through all the steps of getting the calibrated values and creating the string that is passed to the filesystem. In the console, it shows the date and time stamp, the 4 calibrated values. Once it does that, it displays the sending data to sql database and then goes right to data sent.

When I check the database, nothing is there, so I know I have a error somewhere in the arduino code. Last time I had an error with the process parameters that I was passing.

When I run db.php (The php code above) with 8 values on it, the data passes on to the database on the cloud.

The code as it is currently

#include <FileIO.h>
#include <DHT.h>
#include <Process.h>
#include <Console.h>
#include <math.h>

#define DHTPIN 4   
#define DHTTYPE DHT11 
DHT dht(DHTPIN, DHTTYPE);

int sensor1Port = A0; //Thermometer
int sensor2Port = A1;
int sensor3Port = A2;
int sensor4Port = A3;
int sensor5Port = A4;

int sensor1Value = 0;
int sensor2Value = 0;
int sensor3Value = 0;
int sensor4Value = 0;
int sensor5Value = 0;


void setup() {
   Bridge.begin();  // Initialize Bridge
   FileSystem.begin(); //Initialize FileSystem
   Console.begin(); 
      Console.println("You're connected to the Console!!!!");
      Serial.begin(115200);

// initialize digital pin 13 as an output (light to show start of process).
     pinMode(13, OUTPUT);
}

void loop() {
    
// Sensor Slope Intercepts
  
  int slopeSensor1 = 5;
  int interceptSensor1 = 1;
  int slopeSensor2 = 5;
  int interceptSensor2 = 1;
  int slopeSensor3 = 5;
  int interceptSensor3 = 1;
  int slopeSensor4 = 5;
  int interceptSensor4 = 1;
  int slopeSensor5 = 5;
  int interceptSensor5 = 1;
  
//Get the date and time  
  String dataString;
  dataString += getTimeStamp();
  String datestring = dataString;
  
  Console.println(dataString);
  
//DHT11 readings
 int h = dht.readHumidity();
 int t = dht.readTemperature();
  
  Console.println("Ambient Temp:");
  Console.println(t);
  Console.println("Ambient Humidity:");
  Console.println(h);
  
//Light to show start of process  
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level) to show start

//Start Calculations

  int data; //reading from the A/D converter (10-bit)
  float Temp; //the print below does the division first to avoid overflows
  data=analogRead(sensor1Port);       // read count from the A/D converter 
  sensor1Value=Thermistor(data);       // and  convert it to CelsiusSerial.print(Time/1000); //display in seconds, not milliseconds                       
  Console.println("Temp Wand Temp:");
  Console.println(sensor1Value);



//Passing raw values to calculating process
data = analogRead(sensor2Port);
sensor2Value = sensorValueCalculate(slopeSensor2, interceptSensor2, data); 
data = analogRead(sensor3Port);
sensor2Value = sensorValueCalculate(slopeSensor3, interceptSensor3, data);
data = analogRead(sensor4Port);
sensor2Value = sensorValueCalculate(slopeSensor4, interceptSensor4, data);
data = analogRead(sensor5Port);
sensor2Value = sensorValueCalculate(slopeSensor5, interceptSensor5, data);

//Create Datastring to show in console and then write to CSV
dataString += ("," + String(t) + "," + String(h) + "," + String(sensor1Value) + "," + String(sensor2Value) + "," + String(sensor3Value) + "," + String(sensor4Value) + "," + String(sensor5Value));

Console.println(dataString);

File dataFile = FileSystem.open("/mnt/sda1/data.csv", FILE_APPEND);
    dataFile.println(dataString);
    dataFile.close();
    Console.println("Data written to SD Card");

Console.println("Sending data to SQL database");
// Send data to MySQL database  
  Process p;              
   p.begin("/mnt/sda1/db.php");   
   p.addParameter(String(t));
   p.addParameter(String(h)); 
   p.addParameter(String(sensor1Value));
   p.addParameter(String(sensor2Value)); 
   p.addParameter(String(sensor3Value));
   p.addParameter(String(sensor4Value)); 
   p.addParameter(String(sensor5Value));
   p.run();

Console.println("Finished sending data to SQL database");

  digitalWrite(13, LOW);   // turn the LED on (HIGH is the voltage level) to show start
delay(500); //Wait for one hour to run again
}

// This function return a string with the time stamp
String getTimeStamp() {
  String result;
  Process time;
  // date is a command line utility to get the date and the time 
  // in different formats depending on the additional parameter 
  time.begin("date");
  time.addParameter("+%D-%T");  // parameters: D for the complete date mm/dd/yy
                                //             T for the time hh:mm:ss    
  time.run();  // run the command

  // read the output of the command
  while(time.available()>0) {
    char c = time.read();
    if(c != '\n')
      result += c;
  }

  return result;
}

//This function will calculate the calibrated Sensor Value
int sensorValueCalculate(int slope, int intercept, int RawData) {
  Console.println("Calculating");
  int CalibratedReading = intercept + RawData * slope;
  Console.println(CalibratedReading);
  return CalibratedReading;  
}

float Thermistor(int Raw) //This function calculates temperature from ADC count
{
 long Resistance; 
 float Resistor = 15000; //fixed resistor
  float Temp;  // Dual-Purpose variable to save space.
  Resistance=( Resistor*Raw /(1024-Raw)); 
  Temp = log(Resistance); // Saving the Log(resistance) so not to calculate  it 4 times later
  Temp = 1 / (0.00102119 + (0.000222468 * Temp) + (0.000000133342 * Temp * Temp * Temp));
  Temp = Temp - 273.15;  // Convert Kelvin to Celsius                      
  return Temp;                                      // Return the Temperature
}

Since the sketch is printing out the data correctly, and the PHP file updates correctly when called from the command line! it would seem to be something in the way that the data is being passed between the two processes?

Maybe adding some debug prints to the PHP code would help? The PHP code could just print the value so and the sketch could use p.available() to get and print the PHP output. Or the PHP script could just log what it's doing to a file?

Well... If anyone is interested, I fixed the issue. I am not sure exactly what the issue is as I started from a blank sketch and slowly built it up to the point that it had all the code and it works. (I did notice that my final datacollector values all went to the sensor2Value instead of to the correct individual variables.

Here is the final code...

#include <DHT.h>
#include <Process.h>
#include <Console.h>
#include <FileIO.h>
#include <math.h>

#define DHTPIN 4   
#define DHTTYPE DHT11 
DHT dht(DHTPIN, DHTTYPE);

int sensor1Port = A0; //Thermometer
int sensor2Port = A1;
int sensor3Port = A2;
int sensor4Port = A3;
int sensor5Port = A4;

float t = 0;
float h = 0;
int sensor1Value = 0;
int sensor2Value = 0;
int sensor3Value = 0;
int sensor4Value = 0;
int sensor5Value = 0;

void setup() {
   Bridge.begin();  // Initialize Bridge
   Console.begin(); 
//   FileSystem.begin(); //Initialize FileSystem
   Console.println("You're connected to the Console!!!!"); 
   Serial.begin(115200);
      
// initialize digital pin 13 as an output (light to show start of process).
     pinMode(13, OUTPUT);
}

void loop() {

// Sensor Slope Intercepts
  
  int slopeSensor2 = 5;
  int interceptSensor2 = 1;
  int slopeSensor3 = 5;
  int interceptSensor3 = 1;
  int slopeSensor4 = 5;
  int interceptSensor4 = 1;
  int slopeSensor5 = 5;
  int interceptSensor5 = 1;


//Get the date and time to attach to the csv on the micro sd card  
  String dataString;
  dataString += getTimeStamp();
  String datestring = dataString;
  
  Console.println(dataString);
     
//DHT11 readings
 int h = dht.readHumidity();
 int t = dht.readTemperature();
  
  Console.println("Ambient Temp:");
  Console.println(t);
  Console.println("Ambient Humidity:");
  Console.println(h);

//Start Calculations

//Getting reading from temp wand in port 1
  int data; //reading from the A/D converter (10-bit)
  float Temp; //the print below does the division first to avoid overflows
  data=analogRead(sensor1Port);       // read count from the A/D converter 
  sensor1Value=Thermistor(data);       // and  convert it to CelsiusSerial.print(Time/1000); //display in seconds, not milliseconds                       
  Console.println("Temp Wand Temp:");
  Console.println(sensor1Value);

//Passing raw values to calculating process
data = analogRead(sensor2Port);
sensor2Value = sensorValueCalculate(slopeSensor2, interceptSensor2, data); 
  Console.println("Sensor Port 2 Calibrated Value:");
  Console.println(sensor2Value);
data = analogRead(sensor3Port);
sensor3Value = sensorValueCalculate(slopeSensor3, interceptSensor3, data);
  Console.println("Sensor Port 3 Calibrated Value:");
  Console.println(sensor3Value);
data = analogRead(sensor4Port);
sensor4Value = sensorValueCalculate(slopeSensor4, interceptSensor4, data);
  Console.println("Sensor Port 4 Calibrated Value:");
  Console.println(sensor4Value);
data = analogRead(sensor5Port);
sensor5Value = sensorValueCalculate(slopeSensor5, interceptSensor5, data);
  Console.println("Sensor Port 5 Calibrated Value:");
  Console.println(sensor5Value);

//Create Datastring to show in console and then write to CSV
dataString += ("," + String(t) + "," + String(h) + "," + String(sensor1Value) + "," + String(sensor2Value) + "," + String(sensor3Value) + "," + String(sensor4Value) + "," + String(sensor5Value));
  Console.println(dataString);


File dataFile = FileSystem.open("/mnt/sda1/data.csv", FILE_APPEND);
    dataFile.println(dataString);
    dataFile.close();
    Console.println("Data written to SD Card");

 
//Light to show start of database writing process  
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level) to show start

// Send data to MySQL database
Console.println("Sending data to SQL database");
  Process p;              
   p.begin("/mnt/sda1/db.php");
   p.addParameter(String(t));
   p.addParameter(String(h)); 
   p.addParameter(String(sensor1Value));
   p.addParameter(String(sensor2Value)); 
   p.addParameter(String(sensor3Value));
   p.addParameter(String(sensor4Value)); 
   p.addParameter(String(sensor5Value));
   p.run();
   
   Console.println("Finished sending data to SQL database");

  digitalWrite(13, LOW);   // turn the LED on (HIGH is the voltage level) to show start

delay(300000); //Wait for one hour to run again

}

// This function return a string with the time stamp
String getTimeStamp() {
  String result;
  Process time;
  // date is a command line utility to get the date and the time 
  // in different formats depending on the additional parameter 
  time.begin("date");
  time.addParameter("+%D-%T");  // parameters: D for the complete date mm/dd/yy
                                //             T for the time hh:mm:ss    
  time.run();  // run the command

  // read the output of the command
  while(time.available()>0) {
    char c = time.read();
    if(c != '\n')
      result += c;
  }

  return result;
}

//Function to calculate the temperture of port 1
float Thermistor(int Raw) //This function calculates temperature from ADC count
{
 long Resistance; 
 float Resistor = 15000; //fixed resistor
  float Temp;  // Dual-Purpose variable to save space.
  Resistance=( Resistor*Raw /(1024-Raw)); 
  Temp = log(Resistance); // Saving the Log(resistance) so not to calculate  it 4 times later
  Temp = 1 / (0.00102119 + (0.000222468 * Temp) + (0.000000133342 * Temp * Temp * Temp));
  Temp = Temp - 273.15;  // Convert Kelvin to Celsius                      
  return Temp;                                      // Return the Temperature
}

//This function will calculate the calibrated Sensor Value
int sensorValueCalculate(int slope, int intercept, int RawData) {
  Console.println("Calculating");
  int CalibratedReading = intercept + RawData * slope;
  Console.println(CalibratedReading);
  return CalibratedReading;  
}

But all in all, it writes successfully to a mysql database.

Thanks for the suggestions. I am constantly amazed at how helpful forums can be.

Now on to seeing if I can incorporate the webserver into this to display the values when it is sitting there... (Might not work because of power draw...)