This is only a partial answer, about measuring pulse period or duration.
For best accuracy, I would recommend using the “input capture” feature
of a 16-bit timer. This is not as easy as using pulseIn() or timing
the signal with micros(): you will have to carefully study the MCU's
datasheet and manually configure the bits of some I/O registers. You
will be ...
Never directly connect a motor to an Arduino IO pin
You will destroy the Arduino.
An Arduino cannot source (or sink in your case) enough current to drive a motor, and if the motor did manage to turn the huge amounts of EMI it generates would literally blast holes in the silicon inside the chip.
You must use a motor driver of some form. If you only want one ...
To expand a little on Edgar's answer:
There are two main ways of measuring frequency, and both require different resources and are better for different situations.
The method Edgar describes using the Input Capture method, is good for rapidly changing low frequency signals where you want to respond very quickly to changes in the frequency. It works by ...
According to specs I found online, the NodeMCU wants 7-12V on Vin. Most LiPo cells put out around 4 volts, which isn't enough. The battery voltage may drop and the MCU's voltage regulator probably fails to keep putting out 3.3V when the fan's average power draw exceeds some threshold.
It might also be that the fan itself is slowing when the duty cycle ...
It's screaming on you:
sketch_jun13a.ino:7:11: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]
char x = "0";
sketch_jun13a.ino: In function 'void loop()':
sketch_jun13a.ino:21:36: warning: comparison with string literal results in unspecified behavior [-Waddress]
if (Serial.available () && (x == "0")) ...