D1 Mini analogRead very slow at low voltage

I use D1 Mini to measure analog voltages (analogRead()). It works fine except when the voltage being read is below 375 mV, or the read result is less than 100 (out of 1024). I do 300 readings each time. The program times out when the voltage is low. Otherwise, it executes very quickly and getting the correct readings. Is this normal?

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom.. :slight_smile:

kpcharles:
I do 300 readings each time.

What happens (as a test only) when you do for example .... 1 reading at a time when the input analog voltage is below 0.375 volt?

The circuit is attached.

The program code is below:

#define stp D2
#define dir D1
#define MS1 D6
#define MS2 D5
#define MS3 D0
#define EN D7
#define AA D3
#define AB D4

int Di = 0;
int Count = 0;
int S1 = 0;
int S2 = 0;
int S3 = 0;
int val[1000] = {};

//declare a global reset all pins function
void resetBEDPins()
{
digitalWrite(stp, LOW);
digitalWrite(dir, LOW); //clockwise
digitalWrite(MS1, LOW); //000 (full) 100(hal) 010(1/4) 110(1/8) 111(1/16, defualt)
digitalWrite(MS2, LOW);
digitalWrite(MS3, LOW);
digitalWrite(EN, HIGH);
digitalWrite(AA, LOW);
digitalWrite(AB, LOW); //disable all outputs to motor
}

void setup()
{
Serial.begin(921600);
pinMode(A0, INPUT);
pinMode(stp, OUTPUT);
pinMode(dir, OUTPUT);
pinMode(MS1, OUTPUT);
pinMode(MS2, OUTPUT);
pinMode(MS3, OUTPUT);
pinMode(EN, OUTPUT);
pinMode(AA, OUTPUT);
pinMode(AB, OUTPUT);
resetBEDPins(); //All pins reset. Direction=clockwise, full step and enabled
}

void loop()
{
while (Serial.available() > 0)
{
int Di = Serial.parseInt(); //direction?
int Count = Serial.parseInt(); //number of steps
int S1 = Serial.parseInt(); //step size
int S2 = Serial.parseInt();
int S3 = Serial.parseInt();
int S4 = Serial.parseInt();
int S5 = Serial.parseInt();
if (Di == 0){digitalWrite(dir, LOW);} //set direction
else { digitalWrite(dir, HIGH);}
if (S1 == 0){digitalWrite(MS1, LOW);} //set step size
else { digitalWrite(MS1, HIGH);}
if (S2 == 0){digitalWrite(MS2, LOW);}
else { digitalWrite(MS2, HIGH);}
if (S3 == 0){digitalWrite(MS3, LOW);}
else { digitalWrite(MS3, HIGH);}
if (S4 == 0){digitalWrite(AA, LOW);} //choose motor
else { digitalWrite(AA, HIGH);}
if (S5 == 0){digitalWrite(AB, LOW);}
else { digitalWrite(AB, HIGH);}

digitalWrite(EN, LOW); //enable motor
for(int i=0; i<Count; i++) {
digitalWrite(stp,HIGH); //pull stp pin up (Trigger one step)
delay(1);
digitalWrite(stp,LOW); //Pull stp pin low (so it can be triggered again)
delay(1);
val = analogRead(A0); //read the analog input (3.3V = 1024)

  • }*
  • digitalWrite(EN, HIGH); //disable motor *
  • for(int i=0; i<Count; i++) {*
    _ Serial.print(val*); //send the data*_
    * Serial.print(","); //termination character*
    * }*
    }
    }
    As for the question of what happened when only read one data point, it is an excellent question. I tried and the answer is still time out. So when the voltage is below 375 mV, the analogRead () fails.
    Thanks for the help.
    circuit diagram.pdf (62 KB)

I forgot to mentioned that the circuit is simplified. The actual circuit drives four stepped motors and the digital IO pin AA and AB are to control two 1:4 multiplexers so that one stepper motor at a time is being driven.

That's a nice image but not a useful circuit diagram. It being incomplete doesn't help. Hand drawn diagrams are more useful than those pretty pictures.

Also do use code tags for posting your code (as given in the "how to use this forum" sticky that's on top of each forum - and which you probably ignored).

You've defined val as an array, then you're trying to use it as a regular single-variable.

I suspect that has to do with OP's failure to use code tags - from the moment this [i] is expected, the text is in italics.

wvmarle:
I suspect that has to do with OP's failure to use code tags - from the moment this [i] is expected, the text is in italics.

What you suspected is true wvmarle. I just checked a moment ago.... if we do a 'quote' reply for post #3, the code does indeed come out as val[i].

Hi,
PLEASE READ POST #1 and post your code using code tags.

Have you got a simple bit of code that just reads and outputs the value of the analog input.
JUST code for analog input, no other I/O.

If you developed your code in stages you should already have code that just reads the analog input, to test if the hardware and software work.

Tom... :slight_smile:

Thanks to all the help and apologize for not posting the code correctly (my first time). I found out the problem. There is nothing wrong with the code or my D1 Mini. The problem is in the Labview's VISA read utility which I use to read the data from the D1 Mini's com port (so that I can use the powerful Labview software to further process the data).

The VISA read utility needs the byte count to be read to be pre-defined and as the analogRead result drops below 100, the byte count per data read drops from 4 to 3. The utility is waiting for more data that is not coming and therefore timed out.

I plan to convert the integer result into real number with fixed byte count regardless of the value. This should solve the problem.

Thanks again.

Converting to float won't make a difference. You will still get different lengths when using Serial.print() which converts the number to human readable form.

To ensure a fixed length (your value can reach 1,000 or more - so one extra byte than your reading software apparently expects, or below 10 for another byte less) is to use sprintf() and convert it to a 4-digit string, prepending zeros.

char c[5];
sprintf(c, "%04d", val[i]);
Serial.print(c);
Serial.print(F(","));

This will send four characters, zero-padded, then the terminating ,. Note that I added the F() macro: use this to store fixed strings in flash rather than in RAM. Saves a lot of precious variable space, especially when you start getting more and longer strings (and Serial.print() statements).

Thanks for the tips. It works beautifully.

kpcharles:
I found out the problem. There is nothing wrong with the code or my D1 Mini. The problem is in the Labview's VISA read utility which I use to read the data from the D1 Mini's com port (so that I can use the powerful Labview software to further process the data).

Good to hear that you discovered the problem. Good job. Although, do your best (in future) to provide accurate details of the situation. Your opening post only involved Arduino analog read. There was no mention of Labview at all.

The way to approach the problem was to use the arduino alone - by itself, with bare minimum code and hardware - for testing the analog reading, and applying a DC voltage to the analog input pin ---- eg 0.2 volt DC. That would have immediately indicated no problem with the arduino.