Pages: [1]   Go Down
Author Topic: Analogread problem in 1.5.2 as well as 1.5.5-r2  (Read 475 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

0
Offline Offline
Shannon Member
****
Karma: 206
Posts: 12179
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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).
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
#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.
Logged

Pages: [1]   Go Up
Jump to: