Go Down

Topic: Analogread problem in 1.5.2 as well as 1.5.5-r2 (Read 606 times) previous topic - next topic

I don't *think* this particular bug is already on here, but if so I apologize. I have recently found that, when reading from A0, A1, and A2, that A0 & A1 are fine, but A2 seems to periodically report zeros. I thought it could be a temporary thing, so I changed my single read (after a read and a few ms delay to have a clean change from reading the other inputs) to the sum of 8 reads. I still would get a couple of runs through the loop that were correct and then one or more that were zero (meaning 8 zero reads in a row, really). After a few runs of zero, it would go back to being correct. Lather, rinse, repeat.

I connected an Analog Discovery box to the circuit to make sure that the digital pot I was using was not misbehaving, and it wasn't. With no other ideas, I replaced the DUE with a MEGA 2560 and Arduino 1.0.1. Other than commenting out the "analogreadresolution", no changes. The MEGA seems to work perfectly. Several dozen of these loops have completed without a single zero reading.

MarkT

Can you post your code so others can try to reproduce the problem (or at least
confirm if its a known one or a new one).
[ I won't respond to messages, use the forum please ]

Well, it's not pretty, but...

Code: [Select]
#include <TinyGPS.h>
TinyGPS gps;
static void gpsdump(TinyGPS &gps);
static bool feedgps();
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);
volatile int datcol=0, val=0, sum = 0;    
volatile long tim=0, bigsum=0, bigind=0, bigsum1=0, oldbigsum1=0, resvalsum=0, ckint1=0, holdcons0=0;
long cons0=0, tmptim=0, llong=0, llat=0;
volatile long rtc=0, gpsc=0, savrtc=0, savgps=0;
int ar0=0, ar1=0;
long deadtime=0;
int agewarn=0, GPSPWR=7, EQINT=8, RTCINT=9, GPSINT=10, CS=2, CLK=3, UD=4, EQINTLED=32;
int x=0, inByte0='0', inByte1='0', inByte2='0', sval=0;
volatile int inByteTot=0, newinByteTot=0;
unsigned long evArray[4]={0,0,0,0};
int evarraycount=0;

void setup() {
Serial.begin(115200);
Serial2.begin(9600);
pinMode(GPSPWR,OUTPUT);
pinMode(EQINT,INPUT);
pinMode(EQINTLED,OUTPUT);
pinMode(CS,OUTPUT);
pinMode(UD,OUTPUT);
pinMode(CLK,OUTPUT);

inByteTot=40;
chgpot();
digitalWrite(GPSPWR,HIGH);
digitalWrite(EQINTLED,LOW);
attachInterrupt(EQINT,eq,CHANGE);
digitalWrite(EQINT,HIGH);
attachInterrupt(RTCINT,rtcsub,RISING);
attachInterrupt(GPSINT,gpssub,RISING);

analogReadResolution(12);
}

void loop()
{
 int incomingByte=0;
 int ii=0;
 bool newdata = false;
 unsigned long start = millis();
  // Every minute we print an update
  bigsum=0;
  bigind=0;
  bigsum1=0;
  cons0=0;
  holdcons0=0;
 while (millis() - start < 60000)
 {
 if (datcol>0){goto checkeq;} //break out of loop searching for gps data if EQ interrupt triggered
 if (Serial.available()){ //Need to change potentiometer setting
 digitalWrite(EQINTLED,LOW);
     inByte0=Serial.read();
     if (Serial.available()) {
     inByte1=Serial.read();
     if (Serial.available()){
       inByte2=Serial.read();
     }
   }
    newinByteTot=(inByte2-'0')+ (10*(inByte1-'0')) + (100*(inByte0-'0'));
    inByte0='0';
    inByte1='0';
    inByte2='0';
    if(newinByteTot>10 && newinByteTot<110){
      inByteTot=newinByteTot; //only make change if sent a reasonable input
    }
    chgpot();
 }  //End of loop changing pot setting
 
  if (feedgps()){
     newdata = true;
  }
  ar0=analogRead(0);
  delay(4);
  ar1=analogRead(1);
  bigsum+= ar0;
  bigsum1+= ar1;
  if(ar0==0)
  {
  cons0++;
    if(cons0>holdcons0)
    {
    holdcons0=cons0;
    }
  }
  else
  {
    cons0=0;
  }
  delay(1);
  bigind++;
 } //end of while loop that completes every minute

 gpsdump(gps);
checkeq:
 if (datcol>0)
 { ckint1=analogRead(1); // check to see if interrupt was random spike or
   delay(2);      // if amplified signal is actually significantly larger than
   ckint1=analogRead(1);    // previous background
   if(abs((8*ckint1)-oldbigsum1)<100) goto cancel; // get out if not real EQ
   detachInterrupt(EQINT);
   digitalWrite(EQINTLED,HIGH);
   Serial.print("< EQ start ");
   Serial.print(savgps);
   Serial.print(" gps and ");
   Serial.print(savrtc);
   Serial.println(" rtc >");
   while(ii<1000)
       {
         ii++;
         Serial.print("< ");
       sum = 0;
       for (int j = 0; j < 8; j++)
         {
         sum += analogRead(0);
         delay(2);
         }
         Serial.print(sum);
         Serial.print(" ");
         tmptim=millis();
         Serial.print(tmptim);
         Serial.print(" ");
         Serial.print(rtc);
         Serial.print(" ");
         sum=analogRead(1);
         delay(10);
         sum = 0;
         for (int j = 0; j < 8; j++)
             {
             sum += analogRead(1);
             delay(2);
             }
         Serial.print(sum);
         Serial.print(" ");
         tmptim=millis();
         Serial.print(tmptim);
         Serial.print(" ");
         Serial.print(rtc);
         Serial.print(" ");
         Serial.print(gpsc);
         Serial.println(" >");
       } //End of while ii<1000 loop
         Serial.println("< xxx xxx EQ Data Ended xxx xxx >");  // Last
         evArray[evarraycount & 3] = millis(); //update time of most recent EQ int
         evarraycount++; //move pointer to next array element
         if (((millis() - evArray[evarraycount & 3] ) < 1800000) && (inByteTot<110)){//if oldest EQ int < 30 m old and pot not near its limit, change pot
           inByteTot++;
           chgpot();
         }
         datcol=0;
         digitalWrite(EQINTLED,LOW);
         //attachInterrupt(EQINT,eq,HIGH); Replace this line by next two for
         attachInterrupt(EQINT,eq,CHANGE); //less touchy interrupts
         digitalWrite(EQINT,HIGH);

        /* flag++;
        if(flag<4){
          attachInterrupt(EQINT,eq,HIGH);
        }*/
       
 }    //end datcol>0 loop
cancel:
      if(agewarn>0 && (millis()-deadtime)>600000)  //GPS down AND down >10 min
      {        
       digitalWrite(GPSPWR,LOW);    //power cycle
       delay(10000);
       digitalWrite(GPSPWR,HIGH);
       agewarn=0; //reset alarm trip
      }
}    //main loop
static void gpsdump(TinyGPS &gps)
{
 float flat, flon;
 unsigned long age, date, time, chars = 0;
 unsigned short sentences = 0, failed = 0;
 gps.f_get_position(&flat, &flon, &age);
 Serial.print("< ");
 if (datcol > 0){ return;}
 llat=100000*flat;
 print_int(llat,TinyGPS::GPS_INVALID_F_ANGLE,8);
 if (datcol > 0){ return;}
 llong=100000*flon;
 print_int(llong,TinyGPS::GPS_INVALID_F_ANGLE,9);
 if (datcol > 0){ return;}
 Serial.print(age);
 Serial.print(" ");
 if (datcol > 0){ return;}
 if(age<10000)
 {
   agewarn=0;
 }
 if(age>10000  && agewarn==0)
 {  
  deadtime=millis(); //get time of first noticing dead gps
  agewarn=1;
 }
 print_date(gps);
 gps.stats(&chars, &sentences, &failed);
 Serial.println(" >");
}

static void print_int(unsigned long val, unsigned long invalid, int len)
{
 char sz[32];
 if (val == invalid)
   strcpy(sz, "*******");
 else
   sprintf(sz, "%ld", val);
 sz[len] = 0;
 for (int i=strlen(sz); i<len; ++i)
   sz[i] = ' ';
 if (len > 0)
   sz[len-1] = ' ';
 Serial.print(sz);
 feedgps();
}

static void print_date(TinyGPS &gps)
{
 int year;
 int loopi;
 byte month, day, hour, minute, second, hundredths;
 unsigned long age;
 gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
 if (age == TinyGPS::GPS_INVALID_AGE)
   Serial.print("******* ******* ");
 else
 {
   char sz[32];
   sprintf(sz, "%02d%02d%02d %02d %02d %02d %02d ",
       month, day, year, hour, minute, second,hundredths);
   Serial.print(sz);
 }
 Serial.print(age);
 Serial.print(" ");
 Serial.print(rtc);
 Serial.print(" ");
 Serial.print(gpsc);
 resvalsum=analogRead(2);
 resvalsum=0;
 delay(20);
            for (int jjj = 0; jjj < 10; jjj++)
             {
             resvalsum+=analogRead(2); //Pot wiper
             delay(2);
             }
 Serial.print(" ");
 Serial.print(resvalsum);
 Serial.print(" ");
 Serial.print(holdcons0);
 Serial.print(" ");
 Serial.print(bigsum/bigind);
 Serial.print(" ");
   Serial.print(bigsum1/bigind);
 Serial.print(" ");
 Serial.print(inByteTot);
 feedgps();
 oldbigsum1=bigsum1;
}

static void print_str(const char *str, int len)
{
 int slen = strlen(str);
 for (int i=0; i<len; ++i)
   Serial.print(i<slen ? str[i] : ' ');
 feedgps();
}

static bool feedgps()
{
 while (Serial2.available())
 {
   if (gps.encode(Serial2.read()))
     return true;
 }
 return false;
}

void chgpot()
{
     x=0;
     detachInterrupt(EQINT);
     digitalWrite(CS,LOW);     //Low to change resistance, high otherwise
     digitalWrite(UD,LOW);    //UD Low = Decrement = lower voltage, High = Increment
     digitalWrite(CLK,LOW);  //CLK->High, CLK->Low as fast as possible = change resistance 1 unit
     while(x<140){ //Run Vout of Pot all the way to 0 V min to ensure known starting pos
        digitalWrite(CLK,HIGH);
        digitalWrite(CLK,LOW);  
        x++;
        delay(1);
     }
     digitalWrite(EQINTLED,HIGH);
     x=0;
     digitalWrite(UD,HIGH);
     digitalWrite(CLK,LOW);
     while(x<inByteTot){
        digitalWrite(CLK,HIGH);
        digitalWrite(CLK,LOW);  
        x++;
        delay(1);
     }
     attachInterrupt(EQINT,eq,CHANGE); //less touchy interrupts
     digitalWrite(EQINT,HIGH);
     digitalWrite(EQINTLED,LOW);
     digitalWrite(CS,HIGH); // No more writes to dig pot for now
}

void eq()
{
savrtc=rtc;
savgps=gpsc;
tim = millis();
val=digitalRead(EQINT);
if(val==1){
datcol=1;
}
}
void gpssub()
{
gpsc++;
rtc=0;
}
void rtcsub()
{
rtc++;
}


Again, it will work fine for a few minutes ( = a few loops) and then report zeros for the A2 read, called resvalsum in the code. After one to several loops of that, it will return to normal for a minute or a few, and then back to zeros, alternating like that as long as I leave it running. When I program the MEGA with this, it's fine.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy