Interfacing serial vibration meter with arduino and computer

Hey all. I'm trying to make a vibration meter that will sweep a range from 0-10V and record the existing vibration meter's serial output (2 16 character messages per second).

The purpose of this instrument is to capture both the vibration reading and the speed of a fan when the reading was taken (ie volts to a control wire).

I'm using an Uno R3 and AltSoftSerial to extract data from the meter, and the Tx/Rx lines to interface with the computer using processing and usb.

The program works fine when the serial vibration meter isn't on/hooked up, but when there is input from the software serial port it crashes the arduino and freezes it even after the serial connection is severed.

Any idea what's causing this? I have data coming in from one serial port and am outputting it with a voltage reading to another, and somewhere along the way it dies.

Code to come tomorrow.

Any idea what's causing this?

Either your code or your hardware. Pretty vague on both of them.

Code to come tomorrow.

OK. I'll check back tomorrow to see about an answer, then.

There might be some unused variables etc in here, I’m mostly just fumbling my way through. Also it used to output time, no longer needed.

#include <AltSoftSerial.h> 
#include <Time.h>  
#include <Wire.h>
#define TIME_HEADER  "T"   // Header tag for serial time sync message
#define TIME_REQUEST  7    // ASCII bell character requests a time sync message 
///////////////////////////////////////////
#include <LiquidCrystal.h> // initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 11, 12, 3, 13, 2);
#include <stdlib.h>

int counter = 1;
float countvolts = 10;
float countvoltsold = 10;

unsigned long timer;
unsigned long timer2;
unsigned long timer3;
int bytecount;
String appendedinbyte;
String inbytes;
int vibyte;

float voltage[256] = {9.77, 9.77, 9.77, 9.76, 9.74, 9.73, 9.71, 9.68, 9.65, 9.62, 9.59, 9.55, 9.52, 9.48, 9.44, 9.39, 9.35, 9.31, 9.27, 9.22, 9.18, 9.14, 9.10, 9.06, 9.03, 8.99, 8.95, 8.92, 8.88, 8.84, 8.81, 8.77, 8.74, 8.70, 8.66, 8.63, 8.59, 8.56, 8.52, 8.49, 8.45, 8.41, 8.38, 8.34, 8.31, 8.27, 8.23, 8.20, 8.16, 8.13, 8.09, 8.06, 8.02, 7.98, 7.95, 7.91, 7.87, 7.84, 7.80, 7.77, 7.73, 7.69, 7.66, 7.62, 7.58, 7.55, 7.51, 7.47, 7.44, 7.40, 7.36, 7.33, 7.29, 7.26, 7.22, 7.18, 7.15, 7.11, 7.07, 7.04, 7.00, 6.96, 6.93, 6.89, 6.85, 6.82, 6.78, 6.74, 6.71, 6.67, 6.63, 6.59, 6.56, 6.52, 6.48, 6.45, 6.41, 6.37, 6.33, 6.30, 6.26, 6.23, 6.19, 6.15, 6.11, 6.08, 6.04, 6.00, 5.97, 5.93, 5.89, 5.86, 5.82, 5.78, 5.74, 5.71, 5.67, 5.63, 5.59, 5.56, 5.52, 5.48, 5.45, 5.41, 5.37, 5.33, 5.30, 5.26, 5.22, 5.18, 5.15, 5.11, 5.07, 5.03, 5.00, 4.96, 4.92, 4.89, 4.85, 4.81, 4.77, 4.74, 4.70, 4.66, 4.62, 4.59, 4.55, 4.51, 4.47, 4.43, 4.40, 4.36, 4.32, 4.28, 4.25, 4.21, 4.17, 4.13, 4.10, 4.06, 4.02, 3.98, 3.94, 3.91, 3.87, 3.83, 3.79, 3.76, 3.72, 3.68, 3.64, 3.60, 3.57, 3.53, 3.49, 3.45, 3.41, 3.38, 3.34, 3.30, 3.26, 3.22, 3.19, 3.15, 3.11, 3.07, 3.03, 2.99, 2.96, 2.92, 2.88, 2.80, 2.77, 2.73, 2.69, 2.65, 2.61, 2.57, 2.54, 2.50, 2.46, 2.42, 2.38, 2.34, 2.31, 2.27, 2.23, 2.19, 2.15, 2.11, 2.08, 2.04, 2.00, 1.96, 1.92, 1.88, 1.85, 1.81, 1.77, 1.73, 1.69, 1.65, 1.61, 1.557, 1.54, 1.50, 1.46, 1.42, 1.38, 1.34, 1.30, 1.27, 1.23, 1.19, 1.15, 1.11, 1.08, 1.03, 0.98, 0.95, 0.94, 0.90, 0.85, 0.80, 0.74, 0.67, 0.59, 0.52, 0.45, 0.39, 0.34, 0.29, 0.24, 0.20, 0.14, 0.00};

char serialfeed[64];

boolean toggle = true;

AltSoftSerial rs232; // Start the software serial connection
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

void setup()  {
  Serial.begin(9600);
  rs232.begin(9600);
  analogWrite(5, counter); //outputs full voltage for reference
  pinMode(4, INPUT); // OFF-ON-ON Switch
  pinMode(A4, INPUT); // Switch 2
/////////////////////////////////////////////
  lcd.begin(20, 2);
/////////////////////////////////////////////  
  pinMode(13, OUTPUT);
  counter = 1;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

void loop(){    
  //code for reading serial soft port

  if (rs232.available() && toggle == true) { //If data comes in through the serial port, filter and output to the computer. This is set up for an extech vibration meter.


   int inByte = rs232.read();
   bytecount = bytecount + 1;
   if (bytecount > 43 && bytecount <= 47){
   //vibyte = (vibyte*10)+inByte;  
  }
  if (bytecount >= 48) { // resets counter
  bytecount = 0;
   }
  } // if rs232 available
  
  
  
  if (digitalRead(4) == HIGH && digitalRead(A4) == HIGH) {
    toggle = true;
    if  (millis() - timer >= 2000 && counter <=256 && counter != 0) {//if the timer is expired
    
      analogWrite(5, 256- counter); //outputs the voltage to OP AMP
    
      countvolts = voltage[counter];
///////////////////////////////////////////////// 
         Serial.print(countvolts); // Displays Voltage
         Serial.write(vibyte);
//////////////////////////////////////////////////
      lcd.setCursor(0,0); //outputs the information
      lcd.print("SWEEP MODE:         ");
      lcd.setCursor(0,1);
      lcd.print("Vout = ");
      lcd.setCursor(7, 1);
      lcd.print(countvolts);
      lcd.setCursor(11,1);
      lcd.print(" V        ");
  
      counter = counter + 1; 

   timer = millis(); // set timer
    } // if timer expired
    if (counter >256){
    analogWrite(5, 255);
    lcd.setCursor(0,1);
    lcd.print("SWEEP FINISHED =)   ");
  }

  } // if sweep on
  
  
  else if (digitalRead(4) == LOW && digitalRead(A4) == HIGH) { // MIDDLE POSITION
    toggle = true;
    lcd.setCursor(0,0);
    lcd.print("STEP MODE:          ");
    lcd.setCursor(0,1);
    lcd.print("Vout = ");
    lcd.setCursor(11,1);
    lcd.print(" V        "); //THIS CHUNK OF CODE DISPLAYS THE VOLTAGE
    countvoltsold = countvolts;
    if (digitalRead(A1) == HIGH && counter > 1 && millis() - timer2 >= 250){ //ADJUSTS VOLTAGE UP
    counter = counter - 1;
    
    countvolts = voltage[counter];
    
    timer2 = millis();
    }
  }
    
    else if (digitalRead(A3) == HIGH && counter <= 255 && millis() - timer2 >= 250){ // ADJUST VOLTAGE DOWN
    counter = counter + 1;
    countvolts = voltage[counter];
    
    timer2 = millis();
    }
    
    lcd.setCursor(7, 1);
    lcd.print(countvolts);
    if (countvoltsold != countvolts){
    Serial.println(countvolts); // Displays Voltage
    Serial.write(vibyte);
    analogWrite(5, 256-counter); //outputs the voltage to OP AMP
  }
  
  
  
  else if (digitalRead(4) == HIGH && digitalRead(A4) == LOW) { // OFF POSITION
    lcd.setCursor(0,0);
    lcd.print("OPAMP POWER OFF:    ");
    lcd.setCursor(0,1);
    lcd.print("SELECT RUN MODE     ");
    toggle = false;
  }
  
}

A sample of the output is as follows. As you can see, it sometimes trips up. With the above code, it freezes before it can do anything. Not really sure that a whole lot changed though. The “4195020” is the unique identifier of the meter, and the 0’s are the vibration reading in cm/s. Since I’m just trying to get it to work there’s nothing vibrating. It should be noted that this output is not generated by the above code. It’s generated by a similar revision of the code.

41950200000000
41950200000000
41950200000000
41950200000000
9.77
41950200000000
41950200000000
41950200000000
41950200000000
9.76
41950200000000
41950200000000
41950200000000
41950200000000
9.74
41950200000000
41950200000000
41950200000000
41950200000009.73
0
41950200000000
41950200000000
41950200000000
419.71
950200000000
41950200000000
41950200000000
41950200000000
9.68
41950200000000
41950200000000
41950200000000
41950200000000
9.65
41950200000000
41950200000000
41950200000000
41950200000000
9.62
41950200000000
41950200000000
41950200000000
41950200000000
9.59
41950200000000
41950200000000
41950200000000
41950200000000
9.55
41950200000000
41950200000000
41950200000000
41950200000000
float voltage[256] = {9.77, 9.77, 9.77, 9.76, 9.74, 9.73, 9.71, 9.68, 9.65, 9.62, 9.59, 9.55, 9.52, 9.48, 9.44, 9.39, 9.35, 9.31, 9.27, 9.22, 9.18, 9.14, 9.10, 9.06, 9.03, 8.99, 8.95, 8.92, 8.88, 8.84, 8.81, 8.77, 8.74, 8.70, 8.66, 8.63, 8.59, 8.56, 8.52, 8.49, 8.45, 8.41, 8.38, 8.34, 8.31, 8.27, 8.23, 8.20, 8.16, 8.13, 8.09, 8.06, 8.02, 7.98, 7.95, 7.91, 7.87, 7.84, 7.80, 7.77, 7.73, 7.69, 7.66, 7.62, 7.58, 7.55, 7.51, 7.47, 7.44, 7.40, 7.36, 7.33, 7.29, 7.26, 7.22, 7.18, 7.15, 7.11, 7.07, 7.04, 7.00, 6.96, 6.93, 6.89, 6.85, 6.82, 6.78, 6.74, 6.71, 6.67, 6.63, 6.59, 6.56, 6.52, 6.48, 6.45, 6.41, 6.37, 6.33, 6.30, 6.26, 6.23, 6.19, 6.15, 6.11, 6.08, 6.04, 6.00, 5.97, 5.93, 5.89, 5.86, 5.82, 5.78, 5.74, 5.71, 5.67, 5.63, 5.59, 5.56, 5.52, 5.48, 5.45, 5.41, 5.37, 5.33, 5.30, 5.26, 5.22, 5.18, 5.15, 5.11, 5.07, 5.03, 5.00, 4.96, 4.92, 4.89, 4.85, 4.81, 4.77, 4.74, 4.70, 4.66, 4.62, 4.59, 4.55, 4.51, 4.47, 4.43, 4.40, 4.36, 4.32, 4.28, 4.25, 4.21, 4.17, 4.13, 4.10, 4.06, 4.02, 3.98, 3.94, 3.91, 3.87, 3.83, 3.79, 3.76, 3.72, 3.68, 3.64, 3.60, 3.57, 3.53, 3.49, 3.45, 3.41, 3.38, 3.34, 3.30, 3.26, 3.22, 3.19, 3.15, 3.11, 3.07, 3.03, 2.99, 2.96, 2.92, 2.88, 2.80, 2.77, 2.73, 2.69, 2.65, 2.61, 2.57, 2.54, 2.50, 2.46, 2.42, 2.38, 2.34, 2.31, 2.27, 2.23, 2.19, 2.15, 2.11, 2.08, 2.04, 2.00, 1.96, 1.92, 1.88, 1.85, 1.81, 1.77, 1.73, 1.69, 1.65, 1.61, 1.557, 1.54, 1.50, 1.46, 1.42, 1.38, 1.34, 1.30, 1.27, 1.23, 1.19, 1.15, 1.11, 1.08, 1.03, 0.98, 0.95, 0.94, 0.90, 0.85, 0.80, 0.74, 0.67, 0.59, 0.52, 0.45, 0.39, 0.34, 0.29, 0.24, 0.20, 0.14, 0.00};

That’s using 1056 of the 2048 bytes of memory on a 328-based Arduino. What model do you have?

  analogWrite(5, counter); //outputs full voltage for reference

Not even close.

  if (rs232.available() && toggle == true) { //If data comes in through the serial port, filter and output to the computer. This is set up for an extech vibration meter.


   int inByte = rs232.read();
   bytecount = bytecount + 1;
   if (bytecount > 43 && bytecount <= 47){
   //vibyte = (vibyte*10)+inByte;  
  }
  if (bytecount >= 48) { // resets counter
  bytecount = 0;
   }
  } // if rs232 available

I can’t see that this is doing anything useful. At the end, bytecount is the only thing that has changed. Any data that arrived got thrown away.

      analogWrite(5, 256- counter); //outputs the voltage to OP AMP

No, it doesn’t. You really need to read up on what PWM actually does.

It should be noted that this output is not generated by the above code. It’s generated by a similar revision of the code.

So, which code are we debugging?

I’m running an ATMEGA328P
Don’t worry about the analogwrite in setup. I changed the code when i typed up the array backwards and forgot to change this part i guess.

As far as outputting the voltage to the opamp, it works just fine, so I’m not sure what you mean when you say it doesn’t work. Anyways, that’s not the issue at hand. I’m more concerned with being able to read the serial data and output two different serial data streams over usb.

Here’s a less messed-with version of the loop:

vvoid loop(){    
  //code for reading serial soft port

  if (rs232.available() /*&& toggle == false*/) { //If data comes in through the serial port, filter and output to the computer. This is set up for an extech vibration meter.


   int inByte = rs232.read();
   bytecount = bytecount + 1;
   if (bytecount > 55 && bytecount <= 64){
   Serial.write(inByte);
   }
   if (bytecount >= 64) { // resets counter
   bytecount = 0;
   }

  } // if rs232 available
  
  
  
  if (digitalRead(4) == HIGH && digitalRead(A4) == HIGH) {
    if  (millis() - timer >= 2000 && counter <=256 && counter != 0) {//if the timer is expired
    
      analogWrite(5, 256- counter); //outputs the voltage to OP AMP
    
      countvolts = voltage[counter];
/////////////////////////////////////////////////      
        Serial.print(countvolts); // Displays Voltage
        Serial.println();  
//////////////////////////////////////////////////
      lcd.setCursor(0,0); //outputs the information
      lcd.print("SWEEP MODE:         ");
      lcd.setCursor(0,1);
      lcd.print("Vout = ");
      lcd.setCursor(7, 1);
      lcd.print(countvolts);
      lcd.setCursor(11,1);
      lcd.print(" V        ");
  
      counter = counter + 1; 

   timer = millis(); // set timer
    } // if timer expired
    if (counter >256){
    analogWrite(5, 255);
    lcd.setCursor(0,1);
    lcd.print("SWEEP FINISHED ('.')");
  }
  } // if sweep on
  
  
  else if (digitalRead(4) == LOW && digitalRead(A4) == HIGH) { // MIDDLE POSITION
  
    lcd.setCursor(0,0);
    lcd.print("STEP MODE:          ");
    lcd.setCursor(0,1);
    lcd.print("Vout = ");
    lcd.setCursor(11,1);
    lcd.print(" V        "); //THIS CHUNK OF CODE DISPLAYS THE VOLTAGE
    countvoltsold = countvolts;
    if (digitalRead(A1) == HIGH && counter > 1 && millis() - timer2 >= 250){ //ADJUSTS VOLTAGE UP
    counter = counter - 1;
    
    countvolts = voltage[counter];
    
    timer2 = millis();
    }
    
    else if (digitalRead(A3) == HIGH && counter <= 255 && millis() - timer2 >= 250){ // ADJUST VOLTAGE DOWN
    counter = counter + 1;
    countvolts = voltage[counter];
    
    timer2 = millis();
    }
    
    lcd.setCursor(7, 1);
    lcd.print(countvolts);
    if (countvoltsold != countvolts){
    Serial.println(countvolts); // Displays Voltage

    }
    analogWrite(5, 256-counter); //outputs the voltage to OP AMP
    
  }
  
  
  
  else if (digitalRead(4) == HIGH && digitalRead(A4) == LOW) { // OFF POSITION
    lcd.setCursor(0,0);
    lcd.print("OPAMP POWER OFF:    ");
    lcd.setCursor(0,1);
    lcd.print("SELECT RUN MODE     ");
  }
  
}

As far as outputting the voltage to the opamp, it works just fine, so I’m not sure what you mean when you say it doesn’t work

I didn’t say that it didn’t work, for some definition of work. What I said was that the analogWrite() function outputs, on the pin, either 0V or 5V. It does NOT output a variable voltage. What it does is turn the pin on and off so that, to some devices, the pin APPEARS to output something other than 5V. An oscilloscope can see that the output is not something other then 0.0V or 5.0V.

Here’s a less messed-with version of the loop:

But, it won’t compile, so I’m not going to bother reading it.

PaulS:

Kurt_:
As far as outputting the voltage to the opamp, it works just fine, so I'm not sure what you mean when you say it doesn't work.

What I said was that the analogWrite() function outputs, on the pin, either 0V or 5V. It does NOT output a variable voltage.

Kurt, this is what a PWM pin looks like. In this case, this would be analogWrite(x, 190).

The value for analogWrite changes the amount of time the pin stays on, not what analog voltage is output.