Use IR break beam to calculate rpm and then send data to VB program on pc

1st time ever working with Arduino and C+ programming so bear with me.

I using an IR break beam to determine the rpm of a shaft which I then need to send to a program (Simple Dyno) on my pc.

This is the code for the particular break beam setup I am using which was coded to send the results to an LCD found here

/*
 * Optical Tachometer
 *
 * Uses an IR LED and IR phototransistor to implement an optical tachometer.
 * The IR LED is connected to pin 13 and ran continually.
 * Pin 2 (interrupt 0) is connected across the IR detector.
 *
 * Code based on: www.instructables.com/id/Arduino-Based-Optical-Tachometer/
 * Coded by: arduinoprojects101.com
 */

int ledPin = 13;                // IR LED connected to digital pin 13
volatile byte rpmcount;
unsigned int rpm;
unsigned long timeold;

// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

void rpm_fun()
 {
   //Each rotation, this interrupt function is run twice, so take that into consideration for 
   //calculating RPM
   //Update count
      rpmcount++;
 }

void setup()
 {
   lcd.begin(16, 2);  // intialise the LCD

   //Interrupt 0 is digital pin 2, so that is where the IR detector is connected
   //Triggers on FALLING (change from HIGH to LOW)
   attachInterrupt(0, rpm_fun, FALLING);

   //Turn on IR LED
   pinMode(ledPin, OUTPUT);
   digitalWrite(ledPin, HIGH);

   rpmcount = 0;
   rpm = 0;
   timeold = 0;
 }

 void loop()
 {
   //Update RPM every second
   delay(1000);
   //Don't process interrupts during calculations
   detachInterrupt(0);
   //Note that this would be 60*1000/(millis() - timeold)*rpmcount if the interrupt
   //happened once per revolution instead of twice. Other multiples could be used
   //for multi-bladed propellers or fans
   rpm = 30*1000/(millis() - timeold)*rpmcount;
   timeold = millis();
   rpmcount = 0;

   //Print out result to lcd
   lcd.clear();
   lcd.print("RPM=");
   lcd.print(rpm);

   //Restart the interrupt processing
   attachInterrupt(0, rpm_fun, FALLING);
  }

and this is the code the developer of the VB program supplied with his program

/*
  Sketch for use with SimpleDyno
  Developed on Arduino Uno Platform
  DamoRC - 2013-2014
  
  ALWAYS use the Sketch distributed with each new version of SimpleDyno
  
  Transmits:
    1 x Session timestamp 
    1 x Interrupt timestamp and 1 x time interval since last interrupt for INT0 / Pin2 / RPM1
    1 x Interrupt timestamp and 1 x time interval since last interrupt for INT1 / Pin3 / RPM2
    6 x Analog Inputs (A0 and A1 are Voltage and Current, A2 and A3 are Temperature, A4 and A5 are open)
  Values are comma delimeted
  Baud rates selected in SD must match coded values in this Sketch.
 */

  const int NumPortsToRead = 6;
  int AnalogResult[NumPortsToRead];
  volatile unsigned long TimeStamp = 0;
  volatile unsigned long time1 = 0;
  volatile unsigned long time2 = 0;
  volatile unsigned long Oldtime1 = 0;
  volatile unsigned long Oldtime2 = 0;
  volatile unsigned long TempTime1 = 0;
  volatile unsigned long TempTime2 = 0;
  String AllResult = "";

void setup() {
  // Initialize serial communication
  // Ensure that Baud rate specified here matches that selected in SimpleDyno
  // Availailable Baud rates are:
  // 9600, 14400, 19200, 28800, 38400, 57600, 115200
  Serial.begin(9600);
  // Initialize interupts (Pin2 is interrupt 0 = RPM1, Pin3 in interrupt 1 = RPM2)
  attachInterrupt(0,channel1,FALLING);
  attachInterrupt(1,channel2,FALLING);
}

void loop() {
  AllResult = "";
  AllResult += micros();
  AllResult += ",";
  AllResult += TempTime1;
  AllResult += ",";
  AllResult += time1;
  AllResult += ",";
  AllResult += TempTime2;
  AllResult += ",";
  AllResult += time2;
  for (int Looper = 0; Looper < NumPortsToRead;Looper++){
    AnalogResult[Looper] = analogRead(Looper);
    AllResult += ",";
    AllResult += AnalogResult[Looper];
  }
  Serial.println (AllResult);
  Serial.flush();
  delay(1);
}

//Interrupt routine for RPM1
void channel1(){
  TempTime1 = micros();
  time1 = TempTime1-Oldtime1;
  Oldtime1 = TempTime1;
}

//Interrupt routine for RPM2
void channel2(){
    TempTime2 = micros();
  time2 = TempTime2-Oldtime2;
  Oldtime2 = TempTime2;
}

If somebody can help me combine the 2 sketches it would be greatly appreciated! This stuff is completely foreign to me.

A little background on this project. I was roped into doing this for an uncle who was asked by a local school to create this device. My uncle is making the device I just have to create the communication method.

I need this working by next Friday so any help would be appreciated. I read the sticky and I know it’s not anybodies problem but mine that I’m in a rush, but still hoping for help. I’m still gonna work on this myself, to see if I can figure it out in time but I don’t have high hopes for myself.

Been working on this some at work today and came up with this

/*
 * Optical Tachometer
 *
 * Uses an IR LED and IR phototransistor to implement an optical tachometer.
 * The IR LED is connected to pin 13 and ran continually.
 * Pin 2 (interrupt 0) is connected across the IR detector.
 *
 * Code based on: www.instructables.com/id/Arduino-Based-Optical-Tachometer/
 * Coded by: arduinoprojects101.com
 */


const int NumPortsToRead = 6;
  int AnalogResult[NumPortsToRead];
  volatile unsigned long TimeStamp = 0;
  volatile unsigned long time1 = 0;
  volatile unsigned long time2 = 0;
  volatile unsigned long Oldtime1 = 0;
  volatile unsigned long Oldtime2 = 0;
  volatile unsigned long TempTime1 = 0;
  volatile unsigned long TempTime2 = 0;
  String AllResult = "";

int ledPin = 13;                // IR LED connected to digital pin 13
volatile byte rpmcount;
unsigned int rpm;
unsigned long timeold;

void rpm_fun()
 {
   //Each rotation, this interrupt function is run twice, so take that into consideration for 
   //calculating RPM
   //Update count
      rpmcount++;
 }

void setup()
 {
   
   //Interrupt 0 is digital pin 2, so that is where the IR detector is connected
   //Triggers on FALLING (change from HIGH to LOW)
   //attachInterrupt(0, rpm_fun, FALLING);

   attachInterrupt(0,channel1,FALLING);
  //attachInterrupt(1,channel2,FALLING);
   
   
   //Turn on IR LED
   pinMode(ledPin, OUTPUT);
   digitalWrite(ledPin, HIGH);

   rpmcount = 0;
   rpm = 0;
   timeold = 0;
 }

 void loop()
 {
   AllResult = "";
  AllResult += micros();
  AllResult += ",";
  AllResult += TempTime1;
  AllResult += ",";
  AllResult += time1;
  AllResult += ",";
  AllResult += TempTime2;
  AllResult += ",";
  AllResult += time2;
  for (int Looper = 0; Looper < NumPortsToRead;Looper++){
    AnalogResult[Looper] = analogRead(Looper);
    AllResult += ",";
    AllResult += AnalogResult[Looper];
    
    //Update RPM every second
   //delay(1000);
   //Don't process interrupts during calculations
   //detachInterrupt(0);
   //Note that this would be 60*1000/(millis() - timeold)*rpmcount if the interrupt
   //happened once per revolution instead of twice. Other multiples could be used
   //for multi-bladed propellers or fans
   //rpm = 30*1000/(millis() - timeold)*rpmcount;
   //timeold = millis();
   //rpmcount = 0;
  }
   //send out result to pc
   Serial.println (AllResult);
  Serial.flush();
  delay(1);
 }
//Interrupt routine for RPM1
void channel1(){
  TempTime1 = micros();
  time1 = TempTime1-Oldtime1;
  Oldtime1 = TempTime1;

   //Restart the interrupt processing
   attachInterrupt(0, rpm_fun, FALLING);
  }

I ran it through verify/compile on my pc and it didn’t come up with any errors. I don’t have my Arduino here at work so maybe somebody here could give it a once over (before I get a chance to load it tonight) and point out any mistakes/errors.

I still have no idea what I’m doing, but nothing like a crash course to get things started.

I’d like to have the LED for #13 blink when it see’s an interrupt so maybe somebody could point me in the right direction on how to implement this as a verification thing.

Thanks.

This doesn't look right:

  //Restart the interrupt processing
  attachInterrupt(0, rpm_fun, FALLING);

You could probably just delete it and get rid of rpm_fun too.

You should probably stop interrupts at the top of loop and take copies of TempTime1 and time1 to use in your String construction. Turn interrupts on again as soon as the copying is done.

I cannot see those two programs are related.
What do you want to do.? send rpm to PC ?
If that’s the case: use Serial.println(your variable or text);

I have rewritten the rpm_counter a bit.:

/*
 * Optical Tachometer
 *
 * Uses an IR LED and IR phototransistor to implement an optical tachometer.
 * The IR LED is connected to pin 13 and ran continually.
 * Pin 2 (interrupt 0) is connected across the IR detector.
 *
 * Code based on: www.instructables.com/id/Arduino-Based-Optical-Tachometer/
 * Coded by: arduinoprojects101.com
* changed ny k_n
 */

int ledPin = 13;                // IR LED connected to digital pin 13
volatile byte rpmcount;
unsigned int rpm;
unsigned long timeold;
volatile long t1,t2; // holds time_referense for the last revolution
long timePerRev;
float newrpm;
// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

void rpm_fun() // updates time
{
  t2=t1;  t1=micros();
}

void setup()
{
  lcd.begin(16, 2);  // intialise the LCD
  //Interrupt 0 is digital pin 2, so that is where the IR detector is connected
  //Triggers on FALLING (change from HIGH to LOW)
  attachInterrupt(0, rpm_fun, FALLING);
  //Turn on IR LED
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
  rpmcount = 0; // i dont use this one
  rpm = 0; // i dont use this one
  timeold = 0; // i dont use this one
}

void loop()
{
  //Don't process interrupts during calculations
  noInterrupts();
  timePerRev=t2-t1; //time for one (1/2?) revolution
  interrupts() ;
  //Note that this would be 60*1000/(millis() - timeold)*rpmcount if the interrupt
  //happened once per revolution instead of twice. Other multiples could be used
  //for multi-bladed propellers or fans
  newrpm = ..to be calcutated
  //Print out result to lcd
  lcd.clear();
  lcd.print("RPM=");
  lcd.print(rpm);
  // want a delay ?? or do someting else
}

Knut, your right they're not really related. What I'm trying to do is send the signal created by the IR photo transistor when the beam is broken to a program that is installed on my pc.

The guy that created the program supplied the 2nd sketch I posted that will take the data from the Arduino and send it to his program. I just don't know what changes to make to his sketch so it will interpret the signal created when the beam is broken and send it to his program. I apologize if my terminology is wrong and makes thing confusing.

I supplied the 1st sketch in case it was needed for any reason because I don't know enough about this language to be able to supply useful answers ::)

I'll take yours and wildbill's modifications and load them into my Arduino ans see what happens.

Again thanks for all the help guys.

Ok, so I'm pretty much an idiot.

Once I got my IR system wired correctly on the breadboard, I uploaded the sketch (I tried so many different things I'm not sure if I had to take something from the other sketch or not) from the guy that made the program I'm interfacing with and it worked.

What I though was the ground side of my phototransistor was actually the signal side ::) .

Can somebody explain why the guy that designed the IR tachometer that I copied used pin 13 to supply power to the IR led instead of the 5v output? I've seen other layouts that do just that, so I'm wondering the purpose was. Is one method better than the other?

Thank god for solderless breadboards! I'd still be trying to figure this out if I didn't have one.

And thanks to all who offered advice, which as it turned out was my biggest problem, it was the hardware and myself making things harder that it was.

pin Vcc vs 5Vfixed. You can switch on/off under program control.