-->
Page 1 of 1

missing digitalRead() caused by analogRead() in loop

PostPosted: Tue Jul 07, 2020 3:05 pm
by lrossel
Hi,

ESP8266 NodeMCU Dev. Kit

I'm having a problem in control the frequency of a water drop sensed by an IR barrier.

The HW wired is:
- one stepmotor, whose steps are controlled by digital output D3
- one IR sensor to sense the drop of water connected to digital input D0
- one pH probe connected to analog input A0

How is designed:
According a drops flows desired, the time between drops is calculated.
Using the millis() in loop, the programs waits for the time between drops has been reached and start sending steps to the step motor, until a drop is detected by the IR sensor. And the process repeat.
The above process works very smooth and stable.
In addition, the system has to monitor the pH using the analog input A0. This isn't working.

Problem:

When I add a line in loop to read an analog input, sometimes (very often), the program miss one pulse on the digital input, what causes a second drop of water. I already checked with an oscilloscope that the drop is sensed by the IR but the program is nos detecting the digital input.

If I comment the line with the analogRead(), everything works fine by days.

I suspect that the analogRead() process do something with the loop causing some loop cycles are missing just the enough time to miss a water drop signal.

In terms of time, the digital input is ON about 500 micro seconds when a drop is detected.

Code: Select all#define BLYNK_MAX_SENDBYTES 1000
#define BLYNK_PRINT Serial


#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <TimeLib.h>
#include <ESP8266mDNS.h>
#include <EEPROM.h>

#define VIRTUAL_PIN_Terminal 0

#define dosis 2
#define Virtual_Peristaltica 1
#define Analog_read 4
#define Virtual_pH 3
#define Virtual_tpo_gota 5

# define input_gota D0
# define pH_analog A0

#define StepPin D3   // pulse this pin to move one step

float pendiente = 0.0000f;
float constante = 0.0000f;
float pH_val = 0.0000f;
float Calibracion_1 = 20;

SimpleTimer timer;

WidgetTerminal terminal(VIRTUAL_PIN_Terminal); // Attach virtual serial terminal to Virtual Pin




char auth[] = "XXXXXXXXXX"; // Authtoken Deleted by security reasons

bool Peristaltica = false;

bool pH_Enable = false;

float millis_anterior = 0;
float millis_actual = 0;
float delta_millis = 0;
int Conteo_paso = 0;
bool Dosificando = false;
float tiempo_gota = 2;
float millis_gota = 0;
float temp_millis_gota = 0;

bool Bool_StepPin = false;


String bitacora="";
String Resumen = "";
int retardo_mail = 0;
int gota = 0;

bool gota_nueva = true;
float tpo_gota_actual = 0;
float delta_tpo_gota = 0;



BLYNK_CONNECTED() {
  // Synchronize time on connection
  Blynk.syncAll();
  terminal.println();
  terminal.println(F("Blynk v" BLYNK_VERSION));
  terminal.println(F("---------------------"));
  terminal.println(F("**      Listo      **"));
  terminal.println(F("----------------------"));

}

BLYNK_WRITE(dosis)
{
  float pinData = param.asFloat();
  tiempo_gota = ( 60 * 60 * 24 ) / ( pinData * Calibracion_1 );
  if (tiempo_gota < 2) tiempo_gota=2;
}

BLYNK_WRITE(Virtual_Peristaltica)
{
  int pinData = param.asInt();
  Peristaltica = false;
  if ( pinData == 1 ) Peristaltica = true;
}


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); // See the connection status in Serial Monitor
  Wire.begin();
  setSyncInterval(1);
   // Configura entradas y salidas
  pinMode(StepPin, OUTPUT);
  pinMode(input_gota, INPUT);
 
// Una vez conectado a WiFi inicia Blynk con el Token predefinido
  Blynk.config(auth); //Una vez conectado a WiFi se conecta a Blynk
  Blynk.connect(); //Una vez conectado a Blynk notifica al terminal de la app
 
  setSyncInterval(60000);
  EEPROM.begin(1212);
  for (int thisReading = 0; thisReading < numReadings; thisReading++) { readings[thisReading] = 0; }
  eeAddress = 0;
  EEPROM.get(eeAddress, pendiente);
  eeAddress += sizeof(float); //Move address to the next byte after float.
  EEPROM.get(eeAddress, constante);
}

void loop() {
  Blynk.run();
  timer.run();

  millis_actual = millis();

  if ((((millis_actual + millis_gota - tpo_gota_actual)/1000) >= tiempo_gota) and !Dosificando)
  {
//    pH_val = pendiente * analogRead(pH_analog) + constante; / This line has to be commented in order not to miss drops.
    Blynk.virtualWrite(Virtual_pH, pH_val);
    Dosificando = true;
    temp_millis_gota = millis_actual;
  }
  Conteo_paso++;
 
  if ( (Conteo_paso >= 30) and Dosificando )
  {
    digitalWrite(StepPin, !digitalRead(StepPin));
    Conteo_paso = 0;
  }
   gota = digitalRead(input_gota);
   if ( (gota == 1) and Dosificando)
   {
    delta_tpo_gota = (millis_actual-tpo_gota_actual)/1000;
    tpo_gota_actual = millis_actual;
    millis_gota = tpo_gota_actual - temp_millis_gota;
    Blynk.virtualWrite(Virtual_tpo_gota, delta_tpo_gota);
    Dosificando = false;
   }
}

Re: missing digitalRead() caused by analogRead() in loop

PostPosted: Tue Jul 07, 2020 5:53 pm
by lrossel
I decided to try a different approach.

Now I'm using attachInterrupt to handle the digital input from the water drop sensor. The first 10 minutes of testing looks promising.

Re: missing digitalRead() caused by analogRead() in loop

PostPosted: Wed Jul 08, 2020 6:46 am
by lrossel
Still failing. Any ideas?