Connecting a tachometer to arduino uno using hadware serial interface

Hi. I am trying to interface a Monarch ACT-3X digital tachometer to my Arduino Uno so that the output of the meter can be displayed using the Arduino’s serial monitor. I am currently trying to do this using an FTDI USB to TTL serial cable. I have the GND and PWR pins connected to GND and PWR (5V), and have put the cable’s TX pin to the Uno’s RX and the cable’s RX to the Uno’s TX. I am also using a USB type A to B adapter so that I can insert the FTDI chip into the meter. Pictures of my set up can be found in the attachments section of the post.

When I plug the meter directly into my laptop using a USB cable (A to B) and check the meter’s outputs in PUTTY, I get correct readings out. The meter is activated in the Serial monitor for continuous transmission with the command ‘@D1’ which I found in the Serial communication section of the datasheets.

I am relatively new to coding and have written the code attached below to try and communicate so far. My thinking behind it was to send the @D1 command to the Arduino serial monitor using the Serial.write() command so that it would begin communication when attached to the TX and RX pins.

char data;
const int RX = 0;
const int TX = 1;
char init1 = 64;  //ASCII character for @
char init2 = 68;  //ASCII character for D
char init3 = 49;  //ASCII character for 1
char init4 = 13;  //ASCII character for CR

void setup() {
  Serial.begin(9600);         //initialize the serial data
  
  if(Serial){                 //check and display that the communication is working
    Serial.println("Good.");
    delay(1000);
  }
  if(!Serial){                //check and display that the communication is not working
    Serial.println("Bad.");
    delay(1000);
  }

  pinMode(RX, INPUT);
  pinMode(TX, OUTPUT);

  Serial.write(init1);        //print each character of the initialize serial command next to one another using
  Serial.write(init2);        //ASCII  
  Serial.write(init3);
  Serial.write(init4);
  Serial.write("\n");
}

void loop() {
  while(Serial.available() > 0) // Check for availablity of data at Serial Port
  {
    data = Serial.read(); // Reading Serial Data and saving in data variable
    Serial.println(data); // Printing the Serial data
    delay(1000);
  }
}

Any advice and ideas are appreciated. :slight_smile:

The meter is this one:

Panel Tachometer ACT-3X – Monarch Instrument (website)
http://monarchserver.com/Files/pdf/ACT3x_Datasheet_May_19.pdf (datasheet)

The cable is this one:

https://www.digikey.com/product-detail/en/ftdi-future-technology-devices-international-ltd/TTL-232RG-VSW5V-WE/768-1096-ND/2507858

tachometer_custom.ino (1.1 KB)

Please edit and correctly post your code so that mobile users like me can see what you’re doing as we cannot download files. See topic #7 in How to use this forum

It would be helpful to have a schematic of how you have things connected as the source of your troubles sounds like you’ve misunderstood how the serial port works. D0 and D1 are dedicated to the serial port of the Arduino, if you want to have a serial terminal, you cannot connect anything to those two terminals as they’re already in use by the serial to usb converter on the Uno so that the Arduino can send and receive characters with the terminal application in the pc.

To connect a second serial device, you must use software serial since the Uno only has one hardware based serial port. Software serial has speed limitations and some overhead since it is implemented in software only but it will most likely work for simple serial applications.

Thank you for the replay WattsThat. I apologize for my poor posting on the initial one. I have updated it and added the code to the text and have attached pictures of my set up here.

I am going to try and use the SoftwareSerial library to interface. While looking into this library I found info on the AltSoftSerial library as well and was wondering if that was applicable too.

One thing that confuses me with the example codes from the SoftwareSerial library is that the hardware serial is set to a different baud rate than the software serial. How does this work? In the serial monitor itself I see that I need to choose a baud rate and, if it is incorrect, random characters are displayed. If they are running at different baud rates, can I still have both display simultaneously? The overall goal of my project if to have the output of multiple sensors displayed in the serial monitor simultaneously and then saved as a CSV.

Things are becoming more confusing…

The output of the meter is serial RS-232. You have a RS-232 serial to usb converter cable. Those two pieces have no ability to connect directly to an Arduino.

I’m perplexed as to how you can get output from the meter onto the monitor. How are things wired? Could please draw an interconnect diagram?

What is shown in the photo, the usb to serial cable? If so, what’s the usb portion plugged into?

Sorry for the confusion. I’ve drawn my current set up and attached it below.

This set up is for a new code I wrote using the AltSoftSerial library after you recommended the usage of the SoftwareSerial library to read my sensor output. I chose the AltSoftSerial library over the traditional SoftwareSerial as I read that it could simultaneously could transmit and receive data while the traditional SoftwareSerial could not. (source: AltSoftSerial Library, for an extra serial port)

#include <AltSoftSerial.h>

//tachometer digital serial connections
AltSoftSerial tach(8, 9);  //RX and TX
char init1 = 64;  //ASCII character for @
char init2 = 68;  //ASCII character for D
char init3 = 49;  //ASCII character for 1
char init4 = 13;  //ASCII character for CR

void setup() {
  Serial.begin(9600);
  tach.begin(9600);
  while (!Serial) {
    ;
  }
  
  Serial.println("Ready to begin");
  Serial.println("--------------");
  tach.print(init1);  //print ascii @
  tach.print(init2);  //print ascii D
  tach.print(init3);  //print ascii 1
  delay(1000);
  tach.print(init4);  //print ascii CR

  Serial.println("Sent the command to initialize.");
  Serial.println("--------------");
  delay(1000);
}

void loop() {
  if (tach.availableForWrite() > 0) {
    Serial.println("Signal found.");
    Serial.write(tach.read());
  }


}

When I run this code with my current set up, I get the ‘Signal found.’ string back in the loop section of the code but nothing else. This leads me to believe that there is some kind of signal being detected.

Wow, a serious reading comprehension issue on my end. I somehow thought you had a RS-232 output meter, not a usb output meter. Very sorry about that, all is clear to me now.

You changed the message you’re sending to the meter, remove the delay(1000) and add the new line character at the end so it’s the same as the original message in post #0. You could modify your code for better clairity, dropping the init(x) chars by using sprintf with something like this:

  byte str[10];
  sprintf(str, “@D1\r\n”);
  Serial.print(str);

So I have removed my init variables and calls and have placed your recommended code in my set up function. I am pretty new to coding in general and I was wondering if you could explain the byte variable type to me and how to use sprintf. I am getting a lot of errors when I try and implement those three lines and I have copy and pasted an example one below and have attached my current code once again.

CODE:

#include <AltSoftSerial.h>

//tachometer digital serial connections
AltSoftSerial tach(8, 9);  //RX and TX

void setup() {
  Serial.begin(9600);
  tach.begin(9600);
  while (!Serial) {
    ;
  }
  
  Serial.println("Ready to begin");
  Serial.println("--------------");
  byte str[10];
  sprintf(str, "@D1\r\n");
  Serial.print(str);

  Serial.println("Sent the command to initialize.");
  Serial.println("--------------");
  delay(1000);
}

void loop() {
  if (tach.availableForWrite() > 0) {
    Serial.println("Signal found.");
    Serial.write(tach.read());
  }


}

ERROR:
warning: invalid conversion from ‘byte* {aka unsigned char*}’ to ‘char*’ [-fpermissive]

There are a lot more errors but they are all essentially similar to this one.

Update: I removed the error by declaring it as a char variable type rather than byte. Not sure if it is the same thing though. Now, on my outputs, I am getting the string printed with a backwards question mark in front of each line. Where is this coming from?

I read online that weird characters often come from baud rate issues but my baud rate is the same for both serials I declared and for the arduino serial monitor. I tried to check if it was an issue with arduino monitor only and got the same issue in PuTTY. Below is a sample output of my current code.

Ready to begin

@D1
Sent the command to initialize.

Signal found.
⸮Signal found.
⸮Signal found.
⸮Signal found.
⸮Signal found.
⸮Signal found.
⸮Signal found.
⸮Signal found.

I think you should be testing for data in the input buffer

void loop() {
  //if (tach.availableForWrite() > 0) {
    if(tach.available() >0) {
    Serial.println("Signal found.");
    Serial.write(tach.read());
  }

Hi. Thanks for the advice cattledog. I have added that line into my code and now there is no output from the loop section. Therefore there is no data coming in correct?

If there is no data coming in there is an issue with my initialization of the sensor I guess.

Therefore there is no data coming in correct?

That is my understanding.

If there is no data coming in there is an issue with my initialization of the sensor I guess.

I think that you need to send the magic words to the device with the software serial. The sprintf command does not look correct, but it is not needed. Try

//byte str[10];
  //sprintf(str, "@D1\r\n");
  //Serial.print(str);
  tach.print("@D1\r\n");

Or else go back to

tach.print(init1);  //print ascii @
  tach.print(init2);  //print ascii D
  tach.print(init3);  //print ascii 1
  tach.print(init4);  //print ascii CR

Tried to send the string directly to the software serial and got the same result.

I’m running out of ideas.

When I plug the meter directly into my laptop using a USB cable (A to B) and check the meter’s outputs in PUTTY, I get correct readings out. The meter is activated in the Serial monitor for continuous transmission with the command ‘@D1’ which I found in the Serial communication section of the datasheets.

Have you set the meter output baud rate to 9600? If not you should use the menu mode to do that.

Follow the procedure of post #1 and get the meter into the serial output mode using the connection to the computer and PUTTY. I don’t see why the setting would not be persistent.

Then try code like this

#include <AltSoftSerial.h>

//tachometer digital serial connections
AltSoftSerial tach(8, 9);  //RX and TX

void setup() {
  Serial.begin(9600);
  tach.begin(9600);
  }
  
  Serial.println("Ready to begin");
  Serial.println("--------------");
}

void loop() {
  if (tach.available() > 0) {
    Serial.println("Signal found.");
    Serial.write(tach.read());
  }

}

I've set it to 9600 and changed all of its settings through its companion software and tried again with the new code. Same result. No data :(.

I have to download drivers for both the FTDI cable and the tachometer. Is it possible that the arduino is having trouble communicating because it does not have access to these? Is there a way (possibly through libraries?) to get drivers onto the Arduino?

The cable is this one:

https://www.digikey.com/product-detail/en/ftdi-future-technology-devices-international-ltd/TTL-232RG-VSW3V3-WE/768-1072-ND/2441360

USB to UART cable with +3.3V
TTL level UART signals. Maximum
output of 50mA on VCC

I think if you are using the UNO, you might need the 5v TTL version. 3.0v is the minimum voltage specified for a HIGH signal level on a 5v Arduino, but you may have some losses.

I am currently trying to do this using an FTDI USB to TTL serial cable. I have the GND and PWR pins connected to GND and PWR (5V), and have put the cable's TX pin to the Uno's RX and the cable's RX to the Uno's TX

I'm not certain you can power this cable with 5V.

You may find it easier to use the analog voltage output to interface with the Arduino instead of working through all the issues with the Serial output. What is the application, and why to you need the serial interface to the Arduino?

cattledog:
USB to UART cable with +3.3V
TTL level UART signals. Maximum
output of 50mA on VCC

I think if you are using the UNO, you might need the 5v TTL version. 3.0v is the minimum voltage specified for a HIGH signal level on a 5v Arduino, but you may have some losses.

I'm not certain you can power this cable with 5V.

That's my mistake. I posted the link to the 3.3 when I meant to post the one to the 5. I have updated it in post 0. I do in fact have the 5V cable.

cattledog:
You may find it easier to use the analog voltage output to interface with the Arduino instead of working through all the issues with the Serial output. What is the application, and why to you need the serial interface to the Arduino?

I am building upon the work of someone else. They were able to interface the sensor this way. I want to do the serial communication method as it is more accurate without additional analog to digital conversion(ADC) steps and the ADC that was used was very temperature sensitive. If I were to place my finger on it the reading would change drastically. The tachometer is being used in a lab that has very rigid accuracy tolerance so I want to avoid inaccuracy from the ADC.

Can you get access to a scope or logic analyser to see what is on the meter tx/Arduino rx pin?

Is there a signal coming from the meter? If so, what is the voltage level?

If you can get the meter to output directly to a terminal with PUTTY there must be something there, but perhaps the wrong wires of the FTDI connector are being used or there is something else about what is happening within the FTDI we don't understand.

I am building upon the work of someone else. They were able to interface the sensor this way. I want to do the serial communication method as it is more accurate without additional analog to digital conversion(ADC) steps and the ADC that was used was very temperature sensitive. If I were to place my finger on it the reading would change drastically. The tachometer is being used in a lab that has very rigid accuracy tolerance so I want to avoid inaccuracy from the ADC.

There is also a TTL pulse echo out. You could read that with an interrupt, or most accurately with a hardware timer set for external clock source. What is the input signal to the ACT3X?
What is the range of what you are measuring?

I do have access to a scope in order to check the signals being transmitted/received and will do so later today. Regarding the range I am trying to measure, I can measure 0-50k rpm but usually the highest I will see is around 30k rpm.

cattledog:
There is also a TTL pulse echo out. You could read that with an interrupt, or most accurately with a hardware timer set for external clock source. What is the input signal to the ACT3X?

The input signal comes from a laser that is attached via a cable that I think is an aux. Could you explain TTL pulse echo out and how I can read that? I am a novice when it comes to electronics.

I have come to the conclusion that the FTDI chip can't interface with this tachometer. I think it is because the FTDI is reliant on drivers that get installed to the PC, and are received to the FTDI cable through its USB end. These drivers are not present on the tachometer. The way I tested this, using a scope, is as follows.

I attached one FTDI cable from my PC to a breadboard. I connected these pins to another FTDI cable that went to the tachometer. The TX pin from the computer went to the RX of the tachometer cable. The TX of the tachometer cable went to the RX of the computer cable, creating a closed transmission loop between the two devices. I used a scope to probe on the TX of the computer and the RX of the tachometer. There was an identical signal transmitted between these two ports. I then probed on the TX of both and there was no transmission back from the tachometer even though I could see that there was one sent by the computer.

I also probed directly on the pins of the FTDI cable running to the tachometer (I had to disconnect it from the sensor to do this). There was no signal being transmitted by the corresponding pins on its USB cable end. It had power via its free leads.

Therefore, I believe that the FTDI cable was never able to transmit a signal to the tachometer. No signal being transferred means there was no initialize command sent and no data could be returned.

I have come to the conclusion that the FTDI chip can’t interface with this tachometer. I think it is because the FTDI is reliant on drivers that get installed to the PC, and are received to the FTDI cable through its USB end. These drivers are not present on the tachometer.

I’m not sure that correct. Virtual COM port (VCP) drivers cause the USB device to appear as an additional COM port available to the PC. Application software can access the USB device in the same way as it would access a standard COM port.

Have you emailed technical support at Monarch? They might have some advice.

Your scope work definitely shows there is no Serial output going to the Arduino through the FTDI.

Could you explain TTL pulse echo out and how I can read that?

The TTL pulse echo output and connection is described in the ACT3X user manual.

Regarding the range I am trying to measure, I can measure 0-50k rpm but usually the highest I will see is around 30k rpm.

I suggest that you use either the FreqCount.h or the FreqMeasure.h libraries to read this pulse output. If one of these is not satisfactory, writing the specific code you need will be possible. Take a look at the libraries and come back with any questions.

https://www.pjrc.com/teensy/td_libs_FreqCount.html

Can you please explain more about the role of the Arduino in your project. It may help to fine tune the library usage. How are you using the rpm values?