Sensor PING y librería Servo

Ya estaba pensando en una sesión de espiritismo con tu Arduino, no era normal!!

Me alegro de que al final funcione!

Un saludo

Hola de nuevo repitiendo con el tema. Por el momento he quitado lo de "solucionado" porque me ha surgido otro problema relacionado con lo mismo. Tras comprobar el fallo "gordo" por alimentar el servo desde el Arduino ahora surge otro fallo similar pero de menor medida.

Sigo practicando con el sensor Ping, la líbrería servo y también con la librería PID aunque el problema sigue siendo sólo con Ping y servo.
Este es el código que imprime las lecturas del sensor. Está preparado con la librería servo pero no están activadas las correspondientes instrucciones, es decir, como si no estuviera el servo.

#include <Servo.h>

#define BAUD 115200   

#define PINSERVO 9  

Servo MiServo;  

int TiempoMiServo;
int interval = 20;

const int pingPin = 7;
long oldduration;
long duration;
long mm;
unsigned long previousMillis = 0;


void setup() {
  Serial.begin(BAUD);
 
//  MiServo.attach(PINSERVO); 
//  MiServo.writeMicroseconds(1500);
}

void loop () {

   unsigned long currentMillis = millis();
   
// Voy tomando lecturas del sensor cada 20 ms

  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;

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

  duration = pulseIn(pingPin, HIGH);

 long diferencia = oldduration - duration;
 diferencia = abs(diferencia);
 
   long mm = 10 * duration / 29 / 2;

        Serial.print(mm);
        Serial.print(" - ");
        Serial.print(duration);
        Serial.print(" - ");
        Serial.println(diferencia);

oldduration = duration;
TiempoMiServo = map(duration, 300, 7000, 800, 2300);
TiempoMiServo = constrain (TiempoMiServo, 800, 2300);

// MiServo.writeMicroseconds(TiempoMiServo);

  }
  
}

El sensor Ping está siempre totalmente quieto y los resultados que se muestran en pantalla son prácticamente perfectos, el funcionamiento es correcto.
Impresión en pantalla:

362 - 2104 - 1
362 - 2103 - 1
362 - 2104 - 1
362 - 2103 - 1
362 - 2104 - 1
362 - 2104 - 0
362 - 2103 - 1
362 - 2103 - 0
362 - 2104 - 1
362 - 2103 - 1
362 - 2104 - 1
362 - 2103 - 1
362 - 2104 - 1
362 - 2104 - 0
362 - 2104 - 0
362 - 2104 - 0
362 - 2104 - 0
362 - 2104 - 0
362 - 2103 - 1
362 - 2103 - 0
362 - 2103 - 0
362 - 2103 - 0
362 - 2103 - 0

Ahora bien, en cuanto activo las instrucciones del servo:

#include <Servo.h>

#define BAUD 115200   

#define PINSERVO 9  

Servo MiServo;  

int TiempoMiServo;
int interval = 20;

const int pingPin = 7;
long oldduration;
long duration;
long mm;
unsigned long previousMillis = 0;


void setup() {
  Serial.begin(BAUD);
 
  MiServo.attach(PINSERVO); 
  MiServo.writeMicroseconds(1500);
}

void loop () {

   unsigned long currentMillis = millis();
   
// Voy tomando lecturas del sensor cada 20 ms

  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;

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

  duration = pulseIn(pingPin, HIGH);

 long diferencia = oldduration - duration;
 diferencia = abs(diferencia);
 
   long mm = 10 * duration / 29 / 2;

        Serial.print(mm);
        Serial.print(" - ");
        Serial.print(duration);
        Serial.print(" - ");
        Serial.println(diferencia);

oldduration = duration;
TiempoMiServo = map(duration, 300, 7000, 800, 2300);
TiempoMiServo = constrain (TiempoMiServo, 800, 2300);

 MiServo.writeMicroseconds(TiempoMiServo);

  }
  
}

estando el sensor quieto se producen algunas malas lecturas:

362 - 2103 - 1
362 - 2104 - 1
360 - 2089 - 15
357 - 2076 - 13
360 - 2090 - 14
362 - 2104 - 14
362 - 2103 - 1
362 - 2104 - 1
362 - 2103 - 1
362 - 2104 - 1
362 - 2103 - 1
362 - 2104 - 1
362 - 2103 - 1
362 - 2104 - 1
362 - 2103 - 1
362 - 2104 - 1
362 - 2103 - 1
360 - 2090 - 13
360 - 2090 - 0
360 - 2090 - 0
362 - 2103 - 13
362 - 2104 - 1
362 - 2104 - 0
362 - 2103 - 1
362 - 2103 - 0
362 - 2104 - 1
362 - 2103 - 1
362 - 2104 - 1
362 - 2104 - 0
362 - 2103 - 1
362 - 2103 - 0
362 - 2104 - 1
362 - 2103 - 1
357 - 2074 - 29
360 - 2089 - 15
362 - 2104 - 15
362 - 2104 - 0
362 - 2104 - 0
362 - 2104 - 0
362 - 2104 - 0
362 - 2103 - 1
362 - 2104 - 1
362 - 2103 - 1

Cada unas 15 lecturas se producen tres o cuatro incorrectas.
Si cambio el tiempo de muestreo cambia la frecuencia de las malas lecturas.
Y en éstas que pensé que podía deberse al tema de interrupciones tal como ya había salido así que sobre ese código he insertado las instrucciones cli() y sei() encerrando las instrucciones del Ping y las lecturas son perfectas.

Pero me surge una duda y es que si se usan las instrucciones cli() y sei(), ¿de qué manera puede afectar a la librería servo? ¿Podría afectar en el funcionamiento de un motor brushless? ¿Y cómo afectaría a la librería PID y su precisión? Comentar que estoy haciendo pruebas para el control en altura de un motor con hélice utilizando el sensor Ping y un PID.

Perdón por el tocho, además de estas preguntas he pretendido explicar mis resultados por futuras consultas de otros usuarios.

no se si lo dije anteriormente, pero yo no uso la libreria servo y de vez en cuando tambien hay lecturas erroneas. lo solucione usando un filtro modal por software ya que en mi caso era para medir la altura de un tanque.