Lag using CAN-BUS and OBDII for rpm readout, need help possibly to optimise code

Moving this topic here since it might be better suited to this section.

Hey guys, so I went ahead and followed this instructable and made my own CAN-BUS shield and that works, and I'm also able to get the OBDII info I want, in this case, the rpm, using the sparkfun library.

Now, the problem I'm having is that I noticed on the serial output there was some lag behind what I was seeing on the cluster, but apparently serial output can take a while and aside from that it was relatively responsive, just a half second or second behind.

Now, I'm using some ws2812 led's for this project, and basically I want to have them light up according to the vehicle rpm, in the end it's probably going to be a fairly long strip, 145 or 150 led's but I'm starting with 10.

The problem is that there's horrendous lag and it evens seems to get stuck sometimes, not updating for several seconds.

I know a bunch of if/else statements aren't very efficient, so there's probably some way to map out the number of led's and assign a percentage to them, and the rpm so if the rpm is at 70% of it's range, 70% of the leds light up. I just don't know how to do it.

I just don't know if the if/else statements are what's causing this massive lag/delay/unresponsiveness in times or not, and need some help, as this needs to be a quite snappy and responsive thing.

Here is a video showing the issue

And here is my code:

/****************************************************************************
CAN-Bus Demo

Toni Klopfenstein @ SparkFun Electronics
September 2015
https://github.com/sparkfun/CAN-Bus_Shield

This example sketch works with the CAN-Bus shield from SparkFun Electronics.

It enables the MCP2515 CAN controller and MCP2551 CAN-Bus driver, and demos
using the chips to communicate with a CAN-Bus.

Resources:

Development environment specifics:
Developed for Arduino 1.6.5

Based off of original example ecu_reader_logger by:
Sukkin Pang
SK Pang Electronics www.skpang.co.uk

This code is beerware; if you see me (or any other SparkFun employee) 
at the local, and you've found our code helpful, please buy us a round!

For the official license, please check out the license file included with the library.

Distributed as-is; no warranty is given.
*************************************************************************/

#include <Canbus.h>
#include <Wire.h>
#include <FastLED.h>
char UserInput;
int data;
char buffer[456];  //Data will be temporarily stored to this buffer before being written to the file
int RPM;

#define NUM_LEDS 151
#define DATA_PIN 7
#define CLOCK_PIN 8

// Define the array of leds
CRGB leds[NUM_LEDS];



//********************************Setup Loop*********************************//

void setup(){
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);

if(Canbus.init(CANSPEED_500))  /* Initialise MCP2515 CAN controller at the specified speed */
  {
   

   leds[0] = CRGB::Green;
       FastLED.show();
       delay(500);
    
  } else
  {

  } 
   
  delay(1000);

       leds[0] = CRGB::Black;
       leds[1] = CRGB::Black;
       leds[2] = CRGB::Black;
       leds[3] = CRGB::Black;
       leds[4] = CRGB::Black;
       leds[5] = CRGB::Black;
       leds[6] = CRGB::Black;
       leds[7] = CRGB::Black;
       leds[8] = CRGB::Black;
       leds[9] = CRGB::Black;
       leds[10] = CRGB::Black;
       leds[11] = CRGB::Black;
       leds[12] = CRGB::Black;
       leds[13] = CRGB::Black;
       leds[14] = CRGB::Black;
       leds[15] = CRGB::Black;
       leds[16] = CRGB::Black;
       leds[17] = CRGB::Black;
       leds[18] = CRGB::Black;
       leds[19] = CRGB::Black;
       FastLED.show();
       delay(500);
       leds[0] = CRGB::Red;
       leds[1] = CRGB::Red;
       leds[2] = CRGB::Red;
       FastLED.show();
       delay(500); 

  


}



//********************************Main Loop*********************************//

void loop(){

 Canbus.ecu_req(ENGINE_RPM, buffer);

 long RPM = atol(buffer);
 
    if (RPM >= 800) {
    leds[0] = CRGB::Aqua;
   } else {
    leds[0] = CRGB::Black;
   }
       if (RPM >= 850) {
    leds[1] = CRGB::Aqua;
   } else {
    leds[1] = CRGB::Black;
   }
       if (RPM >= 900) {
    leds[2] = CRGB::Aqua;
   } else {
    leds[2] = CRGB::Black;
   }
       if (RPM >= 950) {
    leds[3] = CRGB::Aqua;
   } else {
    leds[3] = CRGB::Black;
   }

           if (RPM >= 1000) {
    leds[4] = CRGB::Aqua;
   } else {
    leds[4] = CRGB::Black;
   }
       if (RPM >= 1050) {
    leds[5] = CRGB::Aqua;
   } else {
    leds[5] = CRGB::Black;
   }
       if (RPM >= 1100) {
    leds[6] = CRGB::Aqua;
   } else {
    leds[6] = CRGB::Black;
   }if (RPM >= 1150) {
    leds[7] = CRGB::Aqua;
   } else {
    leds[7] = CRGB::Black;
   }
       if (RPM >= 1200) {
    leds[8] = CRGB::Aqua;
   } else {
    leds[8] = CRGB::Black;
   }
     if (RPM >= 1250) {
    leds[9] = CRGB::Aqua;
   } else {
    leds[9] = CRGB::Black;
   }
     if (RPM >= 1300) {
    leds[10] = CRGB::Aqua;
   } else {
    leds[10] = CRGB::Black;
   }
    
   FastLED.show();


 delay(100);
 

}

Those delay() calls are probably the main culprit...

Hi,
Each time you use a delay() function in your code, the code basically STOPS for that delay period, no input or output is updated, including serial.

If you need delays, then look up "Blink without Delay" in the "Example" section of the Arduino IDE, or google "Blink without delay". It will show you how to time an ON/OFF event and still let your code flow.

Tom... :slight_smile:

Alright, I'll look into blink without delay, but from what I understand if you don't have a small delay somewhere in your loop it can lead to problems as well? I vaguely remember something about wanting at least 10ms somewhere in the loop to help it run smoothly.

edit: Mouser is slightly cheaper than digikey so I'll give them a shot, they also have more than one transceiver ready to ship. Not sure how fast it will compare to digikey, guess I'll see.