Pages: [1]   Go Down
Author Topic: Need some logic/syntax help!  (Read 2430 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 35
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey guys and gals,

I've been slowly working through some code this morning which is an implementation of the piezo knock pattern sensor, but instead I am using an IR emitter and collector and attempting to measure the gaps between the sensor being blocked, checking those gap intervals against a master key, and either providing a success action or failure action. I have only gotten as far as trying to get the gap values stored properly into an array.

The code works fairly well up to this point except for two problems:
1. The '6' (last) slot on my array (gapArray) changes with the counter I set up (arrayCounter).
     a. All other array slots populate correctly with the time (in ms) of the gap between one sensor block to the next
     b. The incrementation for arrayCounter is in "gapTimer()" near the bottom of the code
2. When all 7 slots are filled and I intend for everything to reset back to start (for another entry) the program jumps straight into gapTimer() and not switchTrack().
     a. I have tried resetting timerSwitchA and timerSwitchB back to 0 in the final function without luck

I tried to explain this as best I can. After several hours of trying to debug and trouble shoot, I decided to see if anyone could look at this with a fresh pair of eyes. This could easily be replicated with a simple push button (pin 7) and LED (pin 6) if anyone is willing to physically see what the problem is. Thanks!

Code:
int ledPin = 6;
int irPin = 7;
int val = 0;
int val2 = 0;
int gapArray[6];
int arrayCounter = 0;
int timerSwitchA = 0;
int timerSwitchB = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(irPin, INPUT);
}

void loop()
{

  val = digitalRead(7); // Reading value from IR collector
 
  Serial.print(val); // Some serial readouts to verify values
  Serial.print(" ");
  Serial.print(timerSwitchA);
  Serial.print(" ");
  Serial.print(timerSwitchB);
  Serial.print(" A0:");
  Serial.print(gapArray[0]);
  Serial.print(" A1:");
  Serial.print(gapArray[1]);
  Serial.print(" A2:");
  Serial.print(gapArray[2]);
  Serial.print(" A3:");
  Serial.print(gapArray[3]);
  Serial.print(" A4:");
  Serial.print(gapArray[4]);
  Serial.print(" A5:");
  Serial.print(gapArray[5]);
  Serial.print(" A6:");
  Serial.print(gapArray[6]);   
  Serial.print(" AC:");
  Serial.println(arrayCounter);
 
  switchTrack(); //Where the business really starts
 
}

void switchTrack()
  {
   if (arrayCounter == 7) // Used to check pattern after all 7 array slots are filled
  {
   checkPattern();
   timerSwitchA = 0;
   timerSwitchB = 0;
  }
 
   if (val == 1) // If the collector is not receiving IR from emitter
  {
    digitalWrite(ledPin, HIGH);
    timerSwitchA = 1;
  }

  if (timerSwitchA == 1 && val == 0)
  {
    timerSwitchB = 2;
  }

  if (timerSwitchA == 1 && timerSwitchB == 2) // Used to check for when the sensor becomes unblocked to move into gapTimer()
  {
  gapTimer();
  }
}

void gapTimer() {
  digitalWrite(ledPin, LOW);
 
    for (int x = 0; x < 2000; x++) // Counts up to 2 seconds at max for each gap
    {
       val2 = digitalRead(7); 
       Serial.println(x);
       
        if (val2 == 1) // When sensor is blocked again, stores current x value in array slot incremented by arrayCounter
       {
         Serial.print(x);
         Serial.print(" ");
         gapArray[arrayCounter] = x;
         arrayCounter++;
         break;
       }
   
    timerSwitchA = 0; // Resets
    timerSwitchB = 0;
  }
}

void checkPattern() { // Will eventually be used to check array values against preprogrammed pattern
 
  timerSwitchA = 0;
  timerSwitchB = 0;
  arrayCounter = 0;
  Serial.print("CHECK PATTERN RAN");
  delay(2000);
 
  for (int y = 0; y < 7; y++) // Used to rest all array values back to 0
  {
    gapArray[y] = 0;
  }
}
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 291
Posts: 25847
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
// Used to check pattern after all 7 array slots
The array is declared with 6 elements, zero to five.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 35
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
// Used to check pattern after all 7 array slots
The array is declared with 6 elements, zero to five.

Well this quickly solved one problem. I'm too rusty on arrays and was mistaken in thinking that defining it as '6' meant it stopped at slot 6 (0-6) and was actually 7 slots. Big thanks.  smiley-mr-green

The issue of the code not resetting properly still exists though.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 291
Posts: 25847
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, when you've fixed all the array indices, post your code.

(note to mods: this is virtually unusable.)
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 35
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well the only thing I changed was the original definition of the array (from 6 to 7) which corrected my first problem. Nothing else has changed.

And what is virtually unusable?
Logged

Austin, TX
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6137
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
the program jumps straight into gapTimer() and not switchTrack().
How have you determined this?  It looks like the only path into gapTimer() is through switchTrack().
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

0
Offline Offline
Newbie
*
Karma: 0
Posts: 35
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I determined it by watching the serial output from the copious amounts of serial prints I included along the way for debugging. The way in which gapTimer() is invoked within switchTrack() is by having timerSwitchA and timerSwitchB at appropriate values (1 and 2 respectively). This is so that the the gapTimer() is invoked upon release of the button, though I may consider changing that. But, it seems that even though I've tried to redefine timerSwitchA and timerSwitchB to 0 at several times in the code, including when the array is filled and the incremental array counter is reset to 0, upon returning to the void loop() and re-running switchTrack(), it doesn't wait for my input and simply goes to gapTimer().
Logged

Austin, TX
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6137
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I guess if I were you, I'd move the serial prints into switchTrack().  That was I definitely see what the values of variables are before gapTimer() gets called.

In your original description you mentioned using a PushButton to simulate the sensor.  Is that how you are testing this code now?
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

0
Offline Offline
Newbie
*
Karma: 0
Posts: 35
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes, I replaced the IR gate with a push button.

I actually just stumbled upon a work around. I only changed the following code within gapTimer() :

Code:
void gapTimer() {
  digitalWrite(ledPin, LOW);
  
    for (int x = 0; x < 500; x++)
    {
       val2 = digitalRead(7);  
       Serial.println(x);
      
        if (x == 499)
        {
          digitalWrite(ledPin, HIGH);
          delay(100);
          digitalWrite(ledPin, LOW);
          delay(100);
          digitalWrite(ledPin, HIGH);
          delay(100);
          digitalWrite(ledPin, LOW);
          delay(100);
          digitalWrite(ledPin, HIGH);
          delay(100);
          digitalWrite(ledPin, LOW);
          arrayCounter = 0;
          for (int y = 0; y < 7; y++) // Used to rest all array values back to 0
        {
        gapArray[y] = 0;
      }
     }
          
        if (val2 == 1) // When sensor is blocked again, stores current x value in array slot incremented by arrayCounter
       {
         Serial.print(x);
         Serial.print(" ");
         gapArray[arrayCounter] = x;
         arrayCounter++;
         break;
       }
  
    timerSwitchA = 0; // Resets
    timerSwitchB = 0;
  }
}

This serves to reset the array and counter if there isn't any input for a few seconds (when x reaches 499) and flash the LED a few times to indicate the reset. For some reason when I reset the counter and array in this fashion, it returns back to the start condition and works fine. So, at worst, if an input is received incorrectly, I'll have to wait a few seconds for it to reset. This isn't really what I was wanting, but it seems to work well enough to move forward with checking the intervals against the intended pattern.
Logged

Austin, TX
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6137
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I assume then you used an appropriate pull-up (which would invert the pin's input) or pull-down resistor?  And a capacitor to handle de-bouncing?
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

0
Offline Offline
Newbie
*
Karma: 0
Posts: 35
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I used a pull down resistor on the button, but no capacitor. I haven't had any issues with de-bouncing in this case.
Logged

Des Moines, WA - USA
Offline Offline
God Member
*****
Karma: 25
Posts: 779
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
void gapTimer()
{
    ...
   
        if ( x == 499 )
        {
            ...
            arrayCounter = 0;
            ...
        }
    ...
}

void switchTrack()
{
    if ( arrayCounter == 500 )
    {

    ...

    if ( (1 == timerSwitchA  && (2 == timerSwitchB) )
    {
        gapTimer();
    }
}


As seen above within 'gapTimer' you reset 'arrayCounter' if 'x' is 499, then back at the top of 'switchTrack' is a check for a condition that will never happen!
« Last Edit: January 26, 2011, 09:49:06 pm by lloyddean » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 35
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Lloyd: Not sure what you're referring to. I don't have an if (arrayCounter == 500) within switchTrack, but I do have an if (arrayCounter == 7). The reset for arrayCounter with the x = 499 condition is the work around so that if nothing takes place between when x = 0 and x = 499 then it resets. It doesn't seem to want to do that from my original code when I tried to reset it after running the final check.

The modified code I posted made it work anyways, though not ideally.
Logged

Austin, TX
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6137
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Your reset inside of gapTimer():

Code:
    timerSwitchA = 0; // Resets
    timerSwitchB = 0;

Happens inside of the for() loop.  Did you mean for that?
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

Pages: [1]   Go Up
Jump to: