Machine Speed Logger
Records the speeds of machines using arduino, PHP, MySQL, and C#

This whole project takes an arduino mega equipped with a W5500 ethernet shield and a proximity sensor (55505-00-02-A-ND) to count gear teeth pulses, calculates the feet per minute the machine is moving at, sends it to a PHP page hosted on my computer which writes the data to a MySQL database which is then graphed using a program I made in C#. Whew!

The circuit is extremely simple. The prox sensor's black cable goes to ground, red goes to 5V, and the white/black stripped one goes to the interrupt pin on the uno (INT1/digital pin 3).

Credit needs to go where it's due - this tutorial here REALLY helped me out with a lot of the Arduino/PHP stuff! So thank you! :D

Step 1: MySQL

For MySQL ... well, it's easy enough to install and all that. I used HeidiSQL to build my table, which has 5 columns:

  • id - auto incrementing/primary key/int
  • date - a varchar, because working with the Date type pissed me off, lol
  • time - a Time
  • machine id - int
  • speed - double
Nothing terribly complicated there!

Step 2: Arduino & Getting the Ethernet Shield to Work

I, being totally unaware of what I was doing, bought a W5500 ethernet shield for an Arduino Uno from digikey. This would prove to be the first wrench thrown in my path - I couldn't get any of those darned Ethernet examples to work! The problem ended up being that I needed to replace the ethernet library with the one found at this link here. There are some instructions on that page to help you with this, too!

The arduino sketch was not terribly complicated. I used an interrupt to count the pulses from the proximity sensor (part number 55505-00-02-A-ND on digikey) and, every 5 seconds in this example (interval), figure out the fpm by calling CheckInterval() and then use the ethernet shield to send it to a PHP page hosted on my computer. The pressid variable will be different depending on which machine we are recording so we can differentiate them in the table later.

Here's my Arduino code:
// Gear Tooth Counter
// http://r.lagserv.net

//Include library files
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>

//Variables we actually want control over
int pressid = 3;
float interval = 30000;  //in milliseconds 

//Initialize global variables
volatile long int c = 0;
int pressSpeed = 0;
unsigned long totalTimeElapsed = 0;
unsigned long previousTimeElapsed = 0;
float minutes = 0;
float feet = 0;
float seconds = 0;
float inches = 0;
float fpm = 0;
float inchespersecond = 0;

//Setup for Ethernet Library 
byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
byte server[] = { 192, 168, 1, 107 };

EthernetClient client;

//------------------------------------------------------
//ARDUINO SETUP
//------------------------------------------------------
void setup() 
{  
  //Disable SD card if one in the slot
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  //Setup interrupt for counting gear teeth
  attachInterrupt(digitalPinToInterrupt(3), pulse, FALLING);

  //Begin serial
  Serial.begin(115200);

  //Wait 15 seconds for the user to connect the ethernet cable
  delay(15000);

  //Begin ethernet
  if (Ethernet.begin(mac) == 0) 
  {
    Serial.println("Failed to configure Ethernet using DHCP");
  }

  //Give ethernet shield a chance to start up
  delay(1000); 
}

//------------------------------------------------------
//MAIN ARDUINO LOOP
//------------------------------------------------------
void loop() 
{
  //If the ISR isn't being triggered we still need to record that the press has been stationary
  if(millis() - previousTimeElapsed > interval + 1000)
  {
    CheckInterval(); 
  }
}

//------------------------------------------------------
//PULSE FUNCTION (ISR) - COUNTS GEAR TEETH
//------------------------------------------------------
void pulse()
{
  //Increment the counter variable
  c++;

  //Check to see if its time to calculate the press speed
  CheckInterval();
}

//------------------------------------------------------
//CHECKINTERVAL - CHECK TO SEE IF INTERVAL HAS ELAPSED AND CALCULATE AVERAGE PRESS SPEED
//------------------------------------------------------
void CheckInterval()
{
  totalTimeElapsed = millis();
  
  //When the interval has elapsed to determine average press speed over that interval
  if(totalTimeElapsed - previousTimeElapsed > interval)
  {
    float teethCounted = c;
    
    //Do some math
    minutes = interval/1000/60;
    feet = teethCounted/8/12;
    fpm = feet/minutes;

    //Print the result
    Serial.print("Feet per minute: "); Serial.print(fpm); Serial.println();

    //Write to MySQL
    DataToMySql();

    //Reset the timer
    previousTimeElapsed = totalTimeElapsed; 

    //Reset the teeth count
    c = 0;
  }
}

//------------------------------------------------------
//DATATOMYSQL - SEND DATA TO PHP PAGES WHICH IN TURNS ADDS IT TO MYSQL
//------------------------------------------------------
void DataToMySql()
{ 
  //Serial.println("HERE WE GO!");
  
  if (client.connect(server, 80)) 
  {
    Serial.println("-> Connected");
    
    // Make a HTTP request:
    client.print( "GET /dbconnect.php?");
    client.print("id=");
    client.print( pressid );
    client.print("&&");
    client.print("speed=");
    client.print( fpm );
    client.println( " HTTP/1.1");
    client.print("Host: ");
    client.println("192.168.107");
    //client.println(server);
    client.println("Connection: close");
    client.println();
    client.stop();
  }
  else 
  {
    // you didn't get a connection to the server:
    Serial.println("--> connection failed/n");
  }
}


	
Step 3: PHP

I really need to preface this by saying this was my first hands-on exposure to PHP, and this step was extremely infuriating as many of the examples I had found online used old, depreciated code. I admit that this is probably far from the best way of doing this ... but hey! It works!

I used WAMPServer to host this file by sticking it in C:\wamp\www

//dbconnect.php
<?php
$servername = "localhost";      // this is usually "localhost" unless your database resides on a different server
$username = "root";  			// enter your username for mysql
$password = "nintendo";  		// enter your password for mysql
$dbname = "test";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
} 

//Grab the current date
date_default_timezone_set('America/Los_Angeles');
$date = date('Y-m-d');
$time = date('H:i:s');

// Prepare the SQL statement
$sql = "INSERT INTO test.test (date, time, machineid, speed) VALUES ('$date', '$time', '".$_GET['id']."', '".$_GET['speed']."')";     

// Execute SQL statement
if ($conn->query($sql) === TRUE) 
{
	echo "New record created successfully";
} else 
{
	echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
?>
Step 4: C#

Obviously I can't effectively share all my C# code here, and also because I'm hoping to possibly sell this, I'll keep my code mostly to myself (muahahaha!). However, here is a picture of the program thus far. It allows you to graph up to 4 different machines in real-time. You can also change the dates of the individual series on the graph so you can compare the same or different presses on the same or different days! Although comparing the same press on the same day might be a bit silly, but you get the idea. For example, if one press runs a job on September 26 and a different press runs the same job on November 26, you can compare the two! So that's kind of cool.

The max speed in this screenshot is only set to 6 because I was simulating records in the table by tapping the prox sensor against a gear on my desk! However I tried out the arduino sketch beforehand on a machine at work and it counted reliably (and very consistently!) at 150 fpm, which is a pretty standard running speed for the more involved work that we run.