ESP8266 tacho

I have a Wemos D1 mini, (ESP8266), a geared dc brushed motor 1 - 40 rpm, induction sensor attached to the output shaft with 36 pulses per revolution, and BTS7960B 43A H-Bridge Motor Driver
The induction sensor runs at 5v input with a voltage divider on the output to 3.3v.

My problem is I get erratic output from the tacho code and seems no matter what I do I cannot fix it.
I have tried with and without the pwm freq change.

int RPWM = 12;
int LPWM = 16;
int L_EN = 13;
int R_EN = 15;


//void setPWMfrequency(int freq){
//   TCCR2B = TCCR2B & 0b11111000 | freq ;
//  }


volatile float time = 0;
volatile float time_last = 0;
volatile float rpm_array[5] = {0, 0, 0, 0, 0};
int pot;

void setup()
{
  //   setPWMfrequency(0x02);// timer 0 , 3.92KHz
  pinMode(2, INPUT);
  pinMode(L_EN, OUTPUT);
  pinMode(R_EN, OUTPUT);
  analogWriteFreq(3920);//set pwm freq for ESP8266

  //Digital Pin 2 Set As An Interrupt
  attachInterrupt(14, fan_interrupt, FALLING);

  // pot = analogRead(0);

  Serial.begin(115200);
  digitalWrite(R_EN, HIGH);
  digitalWrite(L_EN, HIGH);
  analogWrite(RPWM, 100);// default is 0 - 1023
  analogWrite(LPWM, 0);

}

//Main Loop To Calculate RPM and Update LCD Display
void loop()
{




  while (1) {

    //analogWrite(RPWM, 100);
    //  analogWrite(RPWM, 0);

    // pot = analogRead(0);

    //analogWrite(6, map(pot, 0,1023, 0, 255));

    float  rpm = 0;

    //Slow Down The LCD Display Updates
    delay(400);

    //Update The RPM
    /*
      noInterrupts();
      unsigned long copyTime = time;
      interrupts();
    */

    if (time > 0)
    {

      //5 Sample Moving Average To Smooth Out The Data
      rpm_array[0] = rpm_array[1];
      rpm_array[1] = rpm_array[2];
      rpm_array[2] = rpm_array[3];
      rpm_array[3] = rpm_array[4];
      rpm_array[4] = 60 * (1000000 / (time * 36));
      //Last 5 Average RPM Counts Eqauls....
      rpm = (rpm_array[0] + rpm_array[1] + rpm_array[2] + rpm_array[3] + rpm_array[4]) / 5;

      // rpm = 60*(1000000/(time * 36));
      Serial.print(rpm);
      Serial.println(" rpm");
      //Serial.println(pot);
    }

  }
}


//Capture The IR Break-Beam Interrupt
void fan_interrupt()
{
  time = (micros() - time_last);
  time_last = micros();
}

and the output:

pm
3.04 rpm
3.35 rpm
3.66 rpm
3.68 rpm
3.69 rpm
2.95 rpm
103.91 rpm
204.86 rpm
204.85 rpm
204.83 rpm
55759.90 rpm
55659.08 rpm
55558.25 rpm
55558.68 rpm
55559.19 rpm
4.47 rpm
4.40 rpm
3.96 rpm
3.52 rpm
3.01 rpm
2.63 rpm
2.27 rpm
2.28 rpm
2.29 rpm
2.30 rpm

Any ideas?

The induction sensor runs at 5v input with a voltage divider on the output to 3.3v.

This is definitely a divide-and-conquer problem. Generally, I would have expected the tach to be driving an interrupt.

A resistor voltage divider used for voltage level conversion is a bad design decision, IMO. The added capacitance can screw with the waveform.

Also, were you aware that the ESP8266 user-code programmed under ArduinoIDE must return to the host NON-OS task switcher no longer than 30mS to 50mS (depending upon the article reference.)

So, consider that EVERYTIME you loop() code loops, or anytime delay() or yield() are used, the Arduino code stalls while the RF section does work.

It takes a very careful design to make certain that both sides of the task switcher are happy.

You may find this interesting...

Ray

mrburnette:
This is definitely a divide-and-conquer problem. Generally, I would have expected the tach to be driving an interrupt.

A resistor voltage divider used for voltage level conversion is a bad design decision, IMO. The added capacitance can screw with the waveform.

Also, were you aware that the ESP8266 user-code programmed under ArduinoIDE must return to the host NON-OS task switcher no longer than 30mS to 50mS (depending upon the article reference.)

So, consider that EVERYTIME you loop() code loops, or anytime delay() or yield() are used, the Arduino code stalls while the RF section does work.

It takes a very careful design to make certain that both sides of the task switcher are happy.

You may find this interesting...

Ray

This is something I was unaware of. Thanks Ray for the heads up.