Sign up ×
Arduino Stack Exchange is a question and answer site for developers of open-source hardware and software that is compatible with Arduino. It's 100% free, no registration required.

Following is RPM counting program.

It worked in windows perfectly.

However, in ubuntu it always shows weird value.

int pin = 7;  
float rpm;
float duration;
unsigned long val;
float rps;

void setup()
{
    Serial.begin(9600);
}

void loop()
{
    val = pulseIn(pin, LOW,60000000);

    duration= val / 1000000.00;
    rps = 1.00 / duration;
    rpm = 60.00 * rps;

    Serial.print("RPM=\t");
    Serial.print(rpm);

    Serial.print("\t rps= \t");
    Serial.print(rps);
    Serial.print("\t dt=\t");
    Serial.println(duration);
}
share|improve this question
5  
Can you post examples of "weird" values and mention why you judge those values weird? – jfpoilpret Sep 24 '14 at 5:44
4  
It took you already 18 minutes to give an example of "wierd values", therefore it is safe to remove the "This is urgent" statement, which is usually not well received anyway. – jippie Sep 24 '14 at 6:03
    
normally it is like this – zalt Sep 24 '14 at 6:09
4  
If the same Arduino code gives proper results to the Windows machine, then either there's an issue with the Ubuntu machine or something changed on the Arduino side when you connected it to Ubuntu. – JRobert Sep 24 '14 at 12:25
1  
Values come from Arduino IDE serial monitor and my windows is a loptop and Ubuntu is a desktop machine. – zalt Sep 24 '14 at 23:09

2 Answers 2

Which Arduino board are you using? How are you getting revolutions? With hall sensor or opto-reflecting one? Here is my code that gets RPM for 3 motors and get torque from RS485.

Here is photo of my work. RPM counter for 3 motors

And the code used. You can adjust it for your need. mySerial used for RS485 so you can delete it and MegunoLink i used to plot data in PC.

#include <SoftwareSerial.h>
#include <MegunoLink.h>

//Software serial for 485 communication : Tx = pin 9, Rx = pin 8.
SoftwareSerial mySerial(9,8);
TimePlot MyPlot;
//CONSTANTS:
//Pin number for Vishay Telefunken Opto-reflecting TCRT1000 sensors:
Message MyCSVMessage("Stendas");
#define TCRT1                12     
#define TCRT2                11   
#define TCRT3                10

String readString;
String momentas1;
String momentas2;
String momentas3;
//Number of pulse changes per revolutuion:
long PulsesPerRevolution1 = 78;
long PulsesPerRevolution2 = 192;
long PulsesPerRevolution3 = 82;
long minute = 60;
//VARIABLES:
//Number of pulses counted:
long           PulseCount1=0;       
long           PulseCount2=0;       
long           PulseCount3=0;       
//Calculated rotations per minute:
long        Rpm1       =0;       
long        Rpm2       =0;       
long        Rpm3       =0; 
//Time saved to compare
unsigned long TimeOld    =0;
//Achieved signals saved:
boolean       Status1    =0;       
boolean       Status2    =0;      
boolean       Status3    =0;       
//Signals saved to compare:
boolean       StatusOld1 =0;       
boolean       StatusOld2 =0;       
boolean       StatusOld3 =0;

void setup() {
  //Begin serial communication with BAUD rate 9600bps:
  Serial.begin(9600);
  mySerial.begin(57600);

  //Set input pins for TCRT1000:
  pinMode(TCRT1, INPUT);           
  pinMode(TCRT2, INPUT);          
  pinMode(TCRT3, INPUT);          
}

void loop() {
  //

  //Read and save TCRT1000 status:
  Status1=digitalRead(TCRT1);      
  Status2=digitalRead(TCRT2);      
  Status3=digitalRead(TCRT3);      
    //Compare current status with the previous one
    //If changed, then increment the counting:
  if (StatusOld1!=Status1){
    StatusOld1=Status1;
    PulseCount1++;
  }
  if (StatusOld2!=Status2){
    StatusOld2=Status2;
    PulseCount2++;
  }  
  if (StatusOld3!=Status3){
    StatusOld3=Status3;
    PulseCount3++;
  }  
  //Compare time if it exceeds 1s:
  if (millis()-TimeOld>=1000){
   //Get data from RS485: 
   READ01();
   momentas1=between3rdAnd4th(momentas1);
   delay(20);
   READ02();
   momentas2=between3rdAnd4th(momentas2);
   delay(20);
   READ03();
   momentas3=between3rdAnd4th(momentas3);
   delay(20);
   momentas1.trim();
   momentas2.trim();
   momentas3.trim();
   //Calculate RPM:
    Rpm1=PulseCount1*minute/PulsesPerRevolution1;
    Rpm2=PulseCount2*minute/PulsesPerRevolution2;
    Rpm3=PulseCount3*minute/PulsesPerRevolution3;
   //Print RPM
    Serial.println(String(Rpm1)+ " ; "+String(momentas1)+ " | " +String(Rpm2) + " ; " + String(momentas2) + " | " + String(Rpm3) + " ; " + String(momentas3));
//    Serial.println(String(Rpm2) + "," + String(momentas2));
//    Serial.println(String(Rpm3) + "," + String(momentas3));    
   //reset the counting and time
    TimeOld=millis();
    PulseCount1=0;
    PulseCount2=0;
    PulseCount3=0;    
  }
}
 //Get data from RS485:
void READ01(){
  while (mySerial.available()){
    mySerial.read();
  }
    mySerial.println("01READ");
    momentas1="";
    delay(20);

    while (mySerial.available()) { 
      char c = mySerial.read();
      if (c == '\n'){
     break;
      }
      momentas1 += c; 
      }
}
void READ02(){
  while (mySerial.available()){
    mySerial.read();
  }
    mySerial.println("02READ");
    momentas2="";
    delay(20);  
    while (mySerial.available()) { 
     char c = mySerial.read();
     if (c == '\n'){
     break;
      }
      momentas2 += c;       
    }

}
void READ03(){
  while (mySerial.available()){
    mySerial.read();
  }
    mySerial.println("03READ");
    momentas3="";
    delay(20);  
    while (mySerial.available()) { 
      char c = mySerial.read();
      if (c == '\n'){
     break;
      }
      momentas3 += c;       
    }
}
  String between3rdAnd4th(String myString) {
  int pirmas = myString.indexOf(',');
  int antras = myString.indexOf(',', pirmas+1);
  int trecias = myString.indexOf(',', antras+1);
  int ketvirtas = myString.indexOf(',', trecias+1);

  String newStr = myString.substring(antras+1, trecias);
  return newStr;
}

If you have any questions about code or want an advice feel free to ask.

** EDIT **

Ok, so i couldn't wait or your urgent answer and continue the work. Connect your hall sensor PULL UP output to pin 2 and try this code:

volatile byte rpmcount;
unsigned int rpm;
unsigned long timeold;

void setup()
 { //Interrupt 0 is digital pin 2
   //Triggers on FALLING (change from HIGH to LOW)
   attachInterrupt(0, rpm_fun, FALLING);

   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 = 60*1000/(millis() - timeold)*rpmcount;
   timeold = millis();
   rpmcount = 0;

   //Print out result
   Serial.print("RPM=");
   Serial.println(rpm);

   //Restart the interrupt processing
   attachInterrupt(0, rpm_fun, FALLING);
  }
  void rpm_fun()
 {
   //Each rotation, this interrupt function is run
   //Update count
      rpmcount++;
 }

** EDIT 2 ** Debuging of communication

void setup(){
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  Serial.println("I am ready to send some stuff!");}
void loop(){ // run over and over
  if (Serial.available())
    Serial.write(Serial.read());}
share|improve this answer
    
Thank you for code martynas. I am using arduino uno with hall sensor. – zalt Sep 24 '14 at 7:54
    
So it should be less complicated than i had :) Also try to #define pin 7 then in setup pinMode(pin, INPUT); and then count revolutions. Also as i understand there is one magnet on shaft? – Martynas Sep 24 '14 at 7:58
    
Also try MegunoLink if you want to plot data. It is great tool. They have freeware version. – Martynas Sep 24 '14 at 8:03
    
So how things are going on? Give some feedback – Martynas Sep 24 '14 at 9:15
    
Edited my answer and provided code for you to just COPY/PASTE... – Martynas Sep 24 '14 at 10:32

If a sketch works and sends data, there is now way how your operating system can change that. This is especially the case because the textual strings are sent correctly, but somehow the numbers are zeroed.

According to your comment:

[...] my windows is a loptop and Ubuntu is a desktop machine.

My guess about that wasn't too random, let me explain the difference:

  • Your laptop is either powered from batteries or from its galvanic isolated power adapter and because of that your USB connections are floating.
  • Your desktop PC however is powered from mains and connected by a power cable including protective ground. The entire case of your PC, including the USB connectors have a low impedance path to (protective) ground.

The above is of little difference when it comes to power the Arduino, however somehow your sensors fail. Apparently the sensor signal which, when connected through the PC, is also referenced to (protective) ground doesn't 'like' being 'tied' to the mechanical device which is probably also somehow referenced to (protective) ground (ground wire / power cable). Make sure the sensors are electrically isolated from the mechanical device, also ensure that capacitive / inductive coupling is minimal. The latter can be probably be accomplished by lowering impedance of the sensor signal. The possibilities highly depend what type of sensors you used, the cabling, ... You can start experimenting by unmounting the sensors and cabling and holding them in your hand. If that solves the symptoms, you know what the underlying problem is.

share|improve this answer
    
By the way, I forgot to mention that program worked properly for windows in the machine that contain ubuntu.The problem is for indication of Low RPM when output of pulse function (duration) exceeds 0.2 sec. – zalt Sep 25 '14 at 5:34

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.