Refine or ReThink ? Turning LED matrix on and off from Range Data

Hi,

Written the following code, which works quite nicely. (sorry if over commented!)

Got a couple of improvements I'd like to make, would appreciate any advice.

  1. The 8x8 Matrix fills row by row, column by column, from distance data supplied by Range Finder.

How would I go about turning on all 'previous' LEDs, so when an object starts mid-range, the LEDs 'before' that distance value are lit (turned into rows and columns by division and modulo)?

  1. The display often 'misses' pixels, if an object is moved rapidly. Is there a way to 'smooth' the data, or remove outlying data points? If issue 1 above is solved, that may help I imagine.

  2. Generally, any comments on the code in general - Is there a fundamentally better way to go about this? Advice on Elegance, Redundancy, Simplification, Improved math?

Thanks!

the relevant bits of code:

cm = microsecondsToCentimeters(duration);
col = cm % 8;
row = cm / 8;

and

lc.setLed(0, row, col, true);
lc.setLed(0, row -1, col, false);

#include "LedControl.h"


LedControl lc=LedControl(12,11,10,4);
unsigned long delaytime=10;


const int trigPin = 7;
const int echoPin = 8;


void setup() {

  Serial.begin(9600);
  
   /* The MAX72XX is in power-saving mode on startup,
      we have to do a wakeup call  */
   
  lc.shutdown(0,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,5);
  /* and clear the display */
  lc.clearDisplay(0);
}

void sensorLED() {
  
  // Establish variables for duration of the ping, the distance
  // in centimeters, and the col and row vars for the LED matrix.

  long duration, cm, realCM, col, row;

  // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(trigPin, OUTPUT);
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigPin, LOW);


  pinMode(echoPin, INPUT);
  duration = pulseIn(echoPin, HIGH);

// Convert the time into a distance, convert the distance into column 
// and row values for the LED matrix. Use Division & Modulo.

  cm = microsecondsToCentimeters(duration);
  realCM = cm + 2;
  col = cm % 8;
  row = cm / 8;


// row, col - rows fill left to right, columns top to bottom (input bottom of Matrix) - BEST -
// col, row - rows fill left to right, columns top to bottom (input bottom of Matrix)

  lc.setLed(0, row, col, true);
  lc.setLed(0, row -1, col, false);
 
}

  long microsecondsToCentimeters(long microseconds) {
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the
  // object we take half of the distance travelled.

  // The 'ad-hoc' and awkward ' - 2' at the end of the calculation is to light the
  // last two LEDs in the last row (7) - as the Rangefinder has a minimum range of 3cm.

  return microseconds / 29 / 2 -2;
} 


void loop() { 

  // Call the function that does all the work!
  sensorLED();

}

How would I go about turning on all 'previous' LEDs, so when an object starts mid-range, the LEDs 'before' that distance value are lit (turned into rows and columns by division and modulo)?

That question assumes a lot of knowledge of what you want to do that is not contained in your post.

  1. The 8x8 Matrix fills row by row, column by column, from distance data supplied by Range Finder.

That tells us nothing about how a distance value of 17, for instance, maps to the pixels that are lit.

the relevant bits of code:

That means that you know which pixels to light up, because the maximum row and maximum column in that row is known.

Turning on all pixels in rows with lower values seems trivial. Turning on all pixels in the maximum row, up to the maximum, seems trivial.

Or, perhaps I've got row and column switched, but the concept is the same. Some rows get every column lit, while one row gets only some columns lit, OR some columns get every row lit when one column gets only some rows lit.