Timer2 conflict or anything else? between newping and MD_MAX72xx libraries

Hello,

I have this configuration:

  • 2 led matrix 8*8 controlled by MAX7219
  • 1 ultrasonic sensor HC-SR04
  • a little servomotor not yet connected
  • arduino uno
    I want to measure a distance and print the results on the led matrixs.
    Everything works fine without the code of the led matrix: i can mesure up to 500 cm and read good results on terminal monitor.
    When I add the code of the led matrix, using MD_MAX72xx library the system works well but only for small distance, like < 20 cm. when i try to measure for example 150 cm it’s showing only random numbers.

I suppose that there is a timer or interrupts problem between newping and MD_MAX72xx libraries

… any suggestion?

here is my complete code :

#define TRIGGER_PIN    3 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN      5 // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 500 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

int n=0;

#include <NewPing.h>
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

#include <VarSpeedServo.h> 
VarSpeedServo myservo;
#include <MD_MAX72xx.h>
#define	PRINT(s, v)	{ Serial.print(F(s)); Serial.print(v); }

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may 
// need to be adapted
#define	MAX_DEVICES	2



#define  CLK_PIN   13  // or SCK
#define DATA_PIN  11  // or MOSI
#define CS_PIN    10  // or SS




//MD_MAX72XX mx = MD_MAX72XX(CS_PIN, MAX_DEVICES);
MD_MAX72XX mx = MD_MAX72XX(DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);


// Text parameters
#define	CHAR_SPACING	1	// pixels between characters

// Global message buffers shared by Serial and Scrolling functions
#define	BUF_SIZE	40
char message[BUF_SIZE] = {"="};
bool newMessageAvailable = true;


int valore_servo_old =0;
int distanza_old = 1;
unsigned int spike=0;



void setup() {
Serial.begin(9600); // Open serial monitor at 115200 baud to see ping results.
myservo.attach(6);
mx.begin();


}

void loop() {

unsigned int uS = sonar.ping(); 
unsigned int distanza = uS / US_ROUNDTRIP_CM;
 snprintf(message, sizeof(message), "%u", distanza);
   printText(0, MAX_DEVICES-1, message);
//  Serial.print("Distanza: ");
 Serial.print(distanza); // Convert ping time to distance in cm and print result (0 = outside set distance range)
//  Serial.print("cm    - Distanza_old: ");
//  Serial.println(distanza_old);

   delay(50);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
 
  
  
  if (distanza==0) 
{
distanza = distanza_old;
  Serial.print("uno");
}

if (abs(distanza_old-distanza)>35 && spike>=1){
  distanza_old = distanza;
  spike=0;
   
        Serial.print("due");
        Serial.print(abs(distanza_old-distanza));
     }
     
 
else if (abs(distanza_old-distanza)>35)
{
  distanza = distanza_old;
      spike++; 
        Serial.print("due incrementa");
            Serial.print(abs(distanza_old-distanza));
        
     }    
     

  unsigned int valore_servo = constrain(map(distanza, 15,80,170, 60),60,170);

 // Serial.print(" Posizione Servo: ");
//  Serial.print(valore_servo);
  Serial.print("Distanza: ");
  Serial.print(distanza); // Convert ping time to distance in cm and print result (0 = outside set distance range)
  Serial.print("cm    - Distanza_old: ");
  Serial.print(distanza_old);


  Serial.print("     spike : ");
  Serial.println(spike);
  myservo.write(valore_servo,50); // il secondo numero é la velocità, il massimo dovrebbe essere 255
  


  
 
  
}



void printText(uint8_t modStart, uint8_t modEnd, char *pMsg)
// Print the text string to the LED matrix modules specified. 
// Message area is padded with blank columns after printing.
{
  uint8_t   state = 0;
  uint8_t	  curLen;
  uint16_t  showLen;
  uint8_t	  cBuf[8];
  int16_t   col = ((modEnd + 1) * COL_SIZE) - 1;

  mx.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);

  do     // finite state machine to print the characters in the space available
  {
    switch(state)
    {
      case 0:	// Load the next character from the font table
        // if we reached end of message, reset the message pointer
        if (*pMsg == '\0')
        {
          showLen = col - (modEnd * COL_SIZE);  // padding characters
          state = 2;
          break;
        }

        // retrieve the next character form the font file
        showLen = mx.getChar(*pMsg++, sizeof(cBuf)/sizeof(cBuf[0]), cBuf);
        curLen = 0;
        state++;
        // !! deliberately fall through to next state to start displaying

      case 1:	// display the next part of the character
        mx.setColumn(col--, cBuf[curLen++]);

        // done with font character, now display the space between chars
        if (curLen == showLen)  
        {
          showLen = CHAR_SPACING;
          state = 2;
        }
        break;

      case 2: // initialize state for displaying empty columns
        curLen = 0;
        state++;
        // fall through

      case 3:	// display inter-character spacing or end of message padding (blank columns)
        mx.setColumn(col--, 0);
        curLen++;
        if (curLen == showLen) 
          state = 0;
        break;

      default:
        col = -1;   // this definitely ends the do loop
    }
  } while (col >= (modStart * COL_SIZE));

  mx.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::ON);
}

thanks!

Have you looked in the libararies themselves? There seem to be no references to
timers in MD_MAX72XX files, they use SPI. The VarSpeedServo uses timer1 just like
the original Servo library.

The issue may be that you have lots of interrupts flying around during the call to
sonar.ping(), which is disturbing the timing. You may need to inhibit the LED
driving temporarily across that call.

How can I inhibit the LED driving temporarily across that call sonar.ping()?
servo.ping() doesn't work correctly so there's something inside MD_MAX72XX and SPI that interfers with the interrupts of servo.ping()

I've tried to change the Trigger and echo pins, i also replaced the newping library with a similar code, using pulsein, but the same problem is still there

pinMode(trig, OUTPUT);
digitalWrite(trig, LOW);
delayMicroseconds(2);
digitalWrite(trig, HIGH);
delayMicroseconds(5);
digitalWrite(trig, LOW);

// The same pin is used to read the signal from the PING))): a HIGH
// pulse whose duration is the time (in microseconds) from the sending
// of the ping to the reception of its echo off of an object.
pinMode(echo,INPUT);
duration = pulseIn(echo, HIGH);

trampolando:
How can I inhibit the LED driving temporarily across that call sonar.ping()?
servo.ping() doesn't work correctly so there's something inside MD_MAX72XX and SPI that interfers with the interrupts of servo.ping()

I don't know, look at the library source/docs?

The issue is when there are a lot of interrupts flying around the processor is
spending time servicing them, so you won't get consistent timing or promptness
from your main program. Doesn't matter which interrupts, its the processor that's
in contention.

If you are lucky you can just inhibit interrupts around the call to ping(), but you might want
to look and see what the library's actually doing to see if that's likely to work.

I've tried this

noInterrupts(); 
unsigned int uS = sonar.ping(); 
interrupts();

but unfortunately doesnt'works

maybe the solution is something like this

but i don't know how to implement this end() method

This is really strange:
I've disconnected the GND pin from the dot led matrix, and everything now works fine, the matrix led display is showing good distances between 0 and 500 cm, fantastic!
the only problem is that the leds are not so bright... intensity has changed!!!
and my question is :
where does the current flow if ground is disconnected from the matrix led module?
a) SCK
b) MOSI
c) SS

anybody?

Through input pin diodes, potentially burning them out. Don't ever do this!

Your problem is a hardware one clearly, you need to check that you have adequate
power supply and decoupling. My guess is inadequate power, so the power rail
dips/wanders and interfers with the ultrasound module's functioning.

Sort of an XY problem. http://xyproblem.info/
You'll see the advice to post full code and full details of the hardware in the
sticky threads - the reason is that the issue is seldom where you think it is (or
you'd have solved it!)