Serial Reading from Other Device

So I do a lot of playing around with electric vehicles as a hobby and I've wanted to do some independent battery capacity testing. I am using a Cycle Analyst (voltage, amperage, amp-hour, etc. measurement) which has a TX line (9,600 baud, tab delimited, carriage return at the end). I want to use the Arduino to read the data, pipe it to Excel and do a few simple calculations on board, such as low voltage cutoff for discharge. So far, I can read it and I've been sending data to Excel before on other projects, so that should be easy. :cold_sweat: What I am running into is I read individual characters and serial print then as such but I need floating points to make decisions.

Here is my pseudo code:

  1. Check if data available.
  2. Read first character into first value of array.
  3. Check if character is "tab" or "carriage return".
    Yes: End array.
    No: Read into next position.
  4. Convert array to floating point number.
  5. ???
  6. Profit.

The following code is not the original single character read then print but my attempt to turn the string into a float. I'm using the Mega.

void loop()
{
  char CA[7] = {0};
  int count = 0;
  digitalWrite(GREEN1, HIGH); // TEST LED Pin 47
  if(Serial1.available() > 0)
  {
    digitalWrite(GREEN3, HIGH); // OTHER TEST LED Pin 43
    do
    {
     CA[count] = Serial1.read();
     count++;
  }while(CA[count] != 9 || CA[count] != 13 );
  // ASCII values of tab and carriage return
  }
  float voltage = atof(CA);
  Serial.print(voltage);
}

This prints a ton of 0.00 and it seems like every once and awhile reprints the headers I print in the void setup and mysteriously causes pin 49 to flash the LED high at the same time.

    do
    {
     CA[count] = Serial1.read();
     count++;
  }while(CA[count] != 9 || CA[count] != 13 )

So, you know that there is at least one character to read, so you read over and over, as fast as possible, running well beyond the bounds of your array, until you find a tab or a carriage return.

  float voltage = atof(CA);

Then you pass that non-NULL-terminated array full of garbage to a function that expects a NULL terminated array of chars, and expect good results.

Not likely, I'd say.

Update: got my code working and printing properly. Instead of constantly polling the serial port, I have tried to make it interrupt based on RX19 (interrupt 4) on the Mega Since the first bit of the serial should be it going from high to low, I had that trigger the interrupt but then (I think) whenever the serial line goes back low, the interrupt restarts. Disabling interrupts inside the interrupt seems to prevent Serial1.read() from working. Would a timer2 based interrupt be a better solution or is there a better way to do this?

Instead of constantly polling the serial port, I have tried to make it interrupt based on RX19 (interrupt 4) on the Mega

Why? All that an interrupt can tell you is that there is serial data available to read. That is the same thing that a call to SerialN.available() will tell you.

Since the first bit of the serial should be it going from high to low, I had that trigger the interrupt but then (I think) whenever the serial line goes back low, the interrupt restarts.

Depends on how you configured the interrupt event handler.

Would a timer2 based interrupt be a better solution or is there a better way to do this?

No. Polling regularly would be the best way.

Thanks a ton PaulS. Your comments have really steered me in the right direction. :slight_smile: