Need help interfacing with Alicat Mass Flow Controller

Hello All,

I am trying to interface with an Alicat Mass Flow Controller using an Arduino Mega Serial port. The mass flow controller serial port appears to send out TTL voltage levels (0-5V, I checked via my scope) so I just connected its serial pins to the Arduino serial port directly. I am able to read something from the MFC, however, the characters are garbled. I am able to read the data just fine via a PC serial port, however. I made sure that the Baud rates are matched between the devices. I tried to switch baud rates, but no luck.

Via PC I am getting repeated streams that look like this:
A +014.66 +028.07 +0000.0 +0000.0 0000.0 Air

On the arduino I am reading (note I read 64 bytes regardless and the MFC constantly sends updated data so I do not know when the frame begins)
¿¿¿}-e yjÖv6¿©£¿©£¿©£¿£¿¿¿¿¿}-e yjÖv6¿©}

Any thoughts would be appreciated!

Here is my code for the MFC object I am using to communicate:

#ifndef AlicatMFC_h
#define AlicatMFC_h

#include "Arduino.h"

#define ALI_MULTIPLIER 64000

#define SERIAL_TIMEOUT 500

class AlicatMFC
{
  public:
    AlicatMFC();
    void initSerial();
    void sendCommand(char* in, char* out);
  private:
 
};

#endif
#include "Arduino.h"
#include "AlicatMFC.h"

AlicatMFC::AlicatMFC()
{
    // NOTES:  No line ends with line feeds
    // There will be two devices A and B
    // To address a given device type: A $XX or B $XX where XX is a command
    
    // NOTE: Units should be first set to polled mode (not streaming), this must be done for each unit separately by sending: *@=A and *@=B respectively
}

void AlicatMFC::initSerial()
{
    Serial3.begin(9600); // Baud for Alicat is 19200 default
}

void AlicatMFC::sendCommand(char* in, char* out)
{  
  int i = 0;
  
  for (i=0;i<64;i++)
    out[i] = '\0';
  
  unsigned long t;
  
  // send the message to MFC
  Serial3.println(in);
  
  // read response (if any)
  i = 0;
  t = millis();
  
   // read until carriage return or serial timeout
  do {      
    while (Serial3.available()==0)
      if ((millis()-t) > SERIAL_TIMEOUT) { out[0] = 'R'; return; }
    
    out[i++] = Serial3.read();
  } while ((out[i-1]!=13) & (i<64));
  
}

So I think I figured out the problem. The MFC is communicating using RS232. However, when I measured the output voltage, it went from 0-5V, so I figured it was TTL. After I inverted the signal from the MFC, I could read the data with no problem. Now I still cannot send from the Arduino to the MFC, but that could be because the input must be a real RS232 signal, not the weird 0-5V signal it is outputting. Ordered some RS232 to TTL converters also... so we'll see.

What does the datasheet for the MFC say? Do you have a link to that (my only experience with an MFC was for one that was controlled via voltage level, and not RS-232)?

Well they really did not describe the protocol well on the datasheet. However, thinks are working just peachy now. The trouble was that the Arduino uses TTL Serial, but the MFC, while it accepts TTL-level signals, uses the RS232 convention of low voltage = 1 and high voltage = 0. Simply inverting the signals both to and from the MFC solved all communication issues!

To anyone finding this thread years later as I did, I wanted to add some helpful info about communicating with Alicats since I struggled with this for a while. I was able to talk to them over serial (both hardware and software) using the SparkFun Transceiver Breakout - MAX3232 (BOB-11189).

Pinouts:

Alicat TX --> T1IN Alicat RX --> R1OUT

T1OUT --> RX (hardware or software serial on microcontroller) R1IN --> TX (hardware or software serial on microcontroller)

And then it magically works!

And, any info about the protocol details by chance?

Some code snippets to get you started…

#define alicatSerial Serial1

Or use software serial…

To initialize the connection to the Alicat(s):

String unitID = "A";
alicatSerial.begin(19200);
alicatSerial.print("\r\r");
delay(100);
alicatSerial.print("\r\r" + unitID + "0\r"); //put setpoint at 0

Be sure to set the Alicats to Serial communications on the front panel and check the unit ID in RS232 comms. You can have multiple units on the same serial line with different addresses, so change as needed.

Setpoints are set as fraction of full scale*64000. So (flow_set/max_flow)*64000. For a unit with a max flow of 5 and a set point of 0.5, you will send a value of 6400.

float flowSet = 0.5;
float maxFlow = 5.0;
float adjustedFlowSet = (flowSet/maxFlow)*64000;

alicatSerial.print("\r\r" + unitID + (String)adjustedFlowSet + "\r");

To get status info from the MFC, send the following command:

alicatSerial.print(unitID + "\r");

This will return a string with the following values: Unit ID, Pressure, Temp, Vol. Flow, Mass Flow, Setpoint, Gas – which you can then parse.

See page 35 of the manual: http://www.alicat.com/documents/manuals/Gas_Flow_Controller_Manual.pdf