Cleaning up serial comms output, to improve codes size and speed

Hi,
im wanting to improve the way i am transmitting serial data to my PC interface.

            // write  machine state to remote else do nothing

           // Format (Pwr/En Sw,MotorEn,Polarity,7Sw matrix)

           Serial.print(PowerEdgeEn);//power/edge
           Serial.print(",");
           Serial.print(MotorEn); //motoren
           Serial.print(",");
           Serial.print(PolarityEn);
           Serial.print(",");
           Serial.print("127");//Matrix - first is dither still to write
           //Serial.print(DitherEnPin);//Matrix - first is dither still to write
           
           // followed by 6 analogue values

           //(interval,Duration,OnTime,Gapvolts,Offtime,MotSpeed)
           Serial.print(",");
           Serial.print(DitherOffDur);
           Serial.print(",");
           Serial.print(DitherOnDur);
           Serial.print(",");
           Serial.print(ToolOnTime);
           Serial.print(",");
           Serial.print(GapV);
           Serial.print(",");
           Serial.print(ToolOffTime);
           Serial.print(",");
           Serial.print(MotSpd*0.099);
           Serial.println();

The values are comma delimited values,
I have looked at fprint, sprint and snprint but most of the answers have been to stick with sending the serial commands as above.

Ie, quicker to load circular buffer than use arrays to construct an output message.

any thoughts would be appreciated

What's wrong with the way you're doing it now?

Hi wildbill,

If i'm reassured its the best and correct method then I will stick with it.

My code is getting a bit mips hungry and dragging out the process time available on the nano.

I have started work on a solution as i was starting to run out of I/O pins in my project as well, Its being upgraded to an Arduino mega as we speak.

I'm building a controller for a pulsed electrical discharge machine (EDM), I got a bit excited and decided to write a VB6 PC application to run the controller as well.

The serial communication does have a tendency of slowing things down, even using a state machine.

there is not a requirement for two way asynchronous communication all the time as the controller will be either in local or remote control, one way the controller gets commands from the GUI and the other it handles its own operation but transmits its settings to the PC.

My application is also using an I2C backpacked LCD display (using adafruit library) and an I2C DAC (using adafruit library). At least upgrading to the mega will release 2 analogue inputs A4 & A5 as i can then use the mega's additional scl/sda pins.

So basically the serial output method used cant be improved upon ?

wildbill:
What's wrong with the way you're doing it now?

Nothing. It is the least memory intensive, code-size way of sending data. Do not change it.

Thanks Paul,

Code stays as is.

You usually chastise me for atrocious code writing, so to have you compliment good code is an honour for me.

Thanks for your time and attention, though I fear you will struggle to ever make a good coder out of me in the long run. :smiley:

JT007:
So basically the serial output method used cant be improved upon ?

What do you mean by improved?

It sounds like you're having trouble with transmission slowing your program down. That's an inherent problem with serial - it's slow and your code will block once the outgoing buffer is full. How you put that data into the buffer is really irrelevant though so sprintf etc. aren't going to help.

One thing that can help is increasing the baud rate - what are you using? Send less data is another, emit the data as binary rather than csv and have the receiving system deal with it. Send the data less frequently if that's viable or perhaps send it only when it changes. Maybe send only the values that have changed.

Wildbill, The current baud rate is set at 9600 (usual n,8,1). I'm used to selecting slower baud rates to compensate for noise in the comms signal and other data issues. I will try your suggestion of increasing baud rate. My VB application on the PC is happy with either Ascii or Binary (MSComm Control).

Is there an easy function to transmit serial as binary from the arduino.

I'm one of those idiots still using good old VB on a 64 bit win7 machine. Who said it cant be done (even though it really shouldn't be). MS .Net really needed a tool like the ActiveX development tool so it was quick and easy to build components, its now like programming in hexadecimal - I want a quick interface application in 5 mins not write war and peace.

So i guess for sending binary i would just use serial.print(analogValue, BIN); // print as an ASCII-encoded binary

No, use Serial.Write(). I'd create a struct with all your values in and pass that & its size to write.

Two minor suggestions.

Rather than

Serial.print(",");

use

Serial.print(',');

or

Serial.write(',');

And use a higher baud rate. My normal baud rate for communication with my PC is 500,000

Sending data in binary format would be a last resort for me simply because it makes the debugging more difficult.

You have not posted a complete program so we have no idea what datatypes you are using. Organize your datatypes to minimize the number of bytes (or chars) that need to be sent. If you can put all your data into an array of chars it can be sent using Serial.write() which is faster than Serial.print()

...R

hi, buddy
thanks for your suggestions, i'm working through them now.

I have attached the code but unfortunately it will have two outcomes
one there is oodals of the stuff which will probably give you an information overload and secondly you will see how bad i am at writing code - or to be exact copy and pasting the stuff.

Engineers, what can I say

You even get a mention in the header Rob.

EDM_Rev4.1.ino (17.6 KB)

Can you mix and match print and write statements or do you advise changing all to Serial.write

EDM Controller all.pdf (15.1 KB)

JT007:
Can you mix and match print and write statements or do you advise changing all to Serial.write

Mix and match is fine.

It is only because the comma is a single character that you can use write() or print()

...R

Got ya, thanks for the tip.

My code is getting a bit mips hungry and dragging out the process time available on the nano.

My application is also using an I2C backpacked LCD display

Your lcd display routine can be made more efficient. You call this function every pass through loop(). All the unchanging text should be printed only once in setup.

void displayToLCD (){

  //lcd.clear();
  
  lcd.home (); // Set cursor to 0,0
  lcd.print("On "); // Custom text
  lcd.setCursor (3,0);        // Go to Chr 3 position of 1st line
  lcd.print(TimeOn_Dur);
  
//  // Padding 0s
    if (TimeOn_Dur<10){
      lcd.setCursor (4,0);
      lcd.print(" ");
   }
//    else{
//      lcd.setCursor (4,0);
//      lcd.print("0");  
//      } 
//      
   if (TimeOn_Dur<100){
      lcd.setCursor (5,0);
      lcd.print(" ");
   }
//      else{
//      lcd.setCursor (5,0);  
//      lcd.print("0");  
//      }
      
  lcd.setCursor (6,0);
  lcd.print("us");
  lcd.setCursor (0,1);
  lcd.print("Off");
  lcd.setCursor (4,1);        // Go to Chr 3 position of 2nd line
  lcd.print(ToolOffTime);
  if (ToolOffTime<10){
      lcd.setCursor (5,1);
      lcd.print(" ");
  }
  lcd.setCursor (6,1);
  lcd.print("us");
  
  lcd.setCursor (9,0);         // Go to Chr 9 position of 1st line
  lcd.print("Gv");
  lcd.setCursor (12,0);        // Go to Chr 13 position of 1st line
  lcd.print(GapV);

  lcd.setCursor (9,1);         // Go to Chr 13 position of 2nd line
  lcd.print("SPD");
  lcd.setCursor (13,1);        // Go to Chr 13 position of 2nd line
  lcd.print(MotSpd);
    
}

You may also want to consider changing from the LiquidCrystal_I2C.h library to the hd44780.h library. It is available through the library manager. This library was written by Bill Perry who is the guru on these i2c lcd's. I believe it is faster.

Serial.print(DitherOffDur);

Serial.print(",");
Serial.print(DitherOnDur);
Serial.print(",");

Well, you could make it slightly smaller and a bit easier to read with something like:

void printwc(long x) {  // print with trailing comma.
  Serial.print(x);
  Serial.write(',');
}
  :
    printwc(DitherOffDur);
    printwc(DitherOnDur);

It won't save very much code, and probably won't affect execution time at all.

Thanks guys,

very interesting, i'm working through all of your suggestions.

I'm not the fastest at typing so i will get back to you all with feedback when i've had a chance to get through it all.

Cheers Jason

If you jack up the baud rate and implement something to address the issue Cattledog identified, that may be enough. No need for other cleverness and pain if those things get you the speed you need.