[Solved] Bench with counting capabilities

Analog reads take around 104 uS. Your print of:

now [i] = 123456\r\n

at 9600 baud takes 17708 uS. You have added quite a delay to that routine.

No joy, unfortunately. In thinking about this a little harder, I have realised that no-one is going to sit down in a micro-second, so perhaps it would be a little better if the reading were only taken every, say quarter of a second, that way the people also have time to sit down, as in the current model if they sit down gradually, the counter won't count them. Is it possible to do this, preferably without delay, since that will cease the whole program, instead?

Of course. Every second or so compare the reading you got a second ago to the current ones. The differences will be the change.

Very sorry to be a bore, but after having a fiddle myself, I'm still unsure how I would do this. I guess it's probably very simple, but I can't work out how to do it without delay. This is my first project ever with an Arduino, so I would be very grateful if you were able to at least point me in the direction of the right code/instructions; would you be able to? Sorry again.

Having had issues where the amount of pulses received when more than one sensor is covered, I have completely rewritten the code. It doesn't work.

What I'm trying to do here is have it so that should one LDR be detected as being sat on, the arduino scans the remainder, to see if any other LDR is sat on, and if it is, the arduino scans the remainder, to see if any other LDR is sat on... and so on.

At each stage a separate pulse is emitted so that it confirms that an additional seat has been taken.

I'm not really sure why this isn't working, looking at my code, but it seems to me that it probably has something to do with my definition of i, j, k etc, because now when I look at the serial monitor, I only get printed out the value of A0 (the first LDR) as my value of now*. What I had hoped is that making it so that j could not equal i still let i use all the values, but it knows that if j can't equal i then i can't equal j. I think if this problem is resolved it will most likely sort out my other problem, because the code is already considerably slower to the point where it ought to register each 'sitting'.*
Please help if you can!
```
*const byte numberOfSensors = 10;

int ldr_pins[numberOfSensors] = {
  A0, A1, A2, A3, A4, A5, A6, A7, A8, A9};
int now[numberOfSensors] = {
  0,0,0,0,0,0,0,0,0,0};
int then[numberOfSensors] = {
  1000,1000,1000,1000,1000,1000,1000,1000,1000,1000};

int counterPin = A10; //Sets Analog 10 to Counter

const int THRESH = 200; //Sets threshold value to 200

void setup(){
  pinMode(counterPin, OUTPUT); //Sets Counter to OUTPUT
  pinMode(13, OUTPUT); //Sets Pin 13 the LED to Output
  Serial.begin(9600);
}

void loop(){

int flag0 = false;
  int flag1 = false;
  int flag2 = false;
  int flag3 = false;
  int flag4 = false;
  int flag5 = false;
  int flag6 = false;
  int flag7 = false;
  int flag8 = false;

for (int i = 0; i < numberOfSensors; i++){
    now[i] = analogRead(ldr_pins[i]);
    for (int j = 0; j < numberOfSensors != i; j++) {
      now[j] = analogRead(ldr_pins[j]);
      for (int k = 0; k < numberOfSensors != i != j; k++) {
        now[k] = analogRead(ldr_pins[k]);
        for (int l = 0; l < numberOfSensors != i != j !=k; l++) {
          now[l] = analogRead(ldr_pins[l]);
          for (int m = 0; m < numberOfSensors != i != j !=k !=l; m++) {
            now[m] = analogRead(ldr_pins[m]);
            for (int n = 0; n < numberOfSensors != i != j !=k !=l !=m; n++) {
              now[n] = analogRead(ldr_pins[n]);
              for (int o = 0; o < numberOfSensors != i != j !=k !=l !=m !=n; o++) {
                now[o] = analogRead(ldr_pins[o]);
                for (int p = 0; p < numberOfSensors != i != j !=k !=l !=m !=n !=o; p++) {
                  now[p] = analogRead(ldr_pins[p]);
                  for (int q = 0; q < numberOfSensors != i != j !=k !=l !=m !=n !=o !=p; q++) {
                    now[q] = analogRead(ldr_pins[q]);
                    for (int r = 0; r < numberOfSensors != i != j !=k !=l !=m !=n !=o !=p !=q; r++) {
                      now[r] = analogRead(ldr_pins[r]);
                      Serial.print ("now [i] = ");
                      Serial.println (now [i]); //debugging

if (now[i] > (then[i] + THRESH) )  {
                        digitalWrite(counterPin, HIGH);
                        digitalWrite(13, HIGH);
                        Serial.println ("Someone sat on the bench."); // more debugging
                        flag0 = true;
                      }
                      else { 
                        digitalWrite(counterPin, LOW);
                        digitalWrite(13, LOW);
                      }
                      then[i] = now[i];

if (flag0 && (now[j] > (then[j] + THRESH))) {
                        digitalWrite(counterPin, HIGH);
                        digitalWrite(13, HIGH);
                        Serial.println ("Someone sat on the bench."); // more debugging
                        flag1 = true;
                      }
                      else { 
                        digitalWrite(counterPin, LOW);
                        digitalWrite(13, LOW);
                      }
                      then[j] = now[j];

if (flag1 && (now[k] > (then[k] + THRESH))) {
                        digitalWrite(counterPin, HIGH);
                        digitalWrite(13, HIGH);
                        Serial.println ("Someone sat on the bench."); // more debugging
                        flag2 = true;
                      }
                      else { 
                        digitalWrite(counterPin, LOW);
                        digitalWrite(13, LOW);
                      }
                      then[k] = now[k];

if (flag2 && (now[l] > (then[l] + THRESH))) {
                        digitalWrite(counterPin, HIGH);
                        digitalWrite(13, HIGH);
                        Serial.println ("Someone sat on the bench."); // more debugging
                        flag3 = true;
                      }
                      else { 
                        digitalWrite(counterPin, LOW);
                        digitalWrite(13, LOW);
                      }
                      then[l] = now[l];

if (flag3 && (now[m] > (then[m] + THRESH))) {
                        digitalWrite(counterPin, HIGH);
                        digitalWrite(13, HIGH);
                        Serial.println ("Someone sat on the bench."); // more debugging
                        flag4 = true;
                      }
                      else { 
                        digitalWrite(counterPin, LOW);
                        digitalWrite(13, LOW);
                      }
                      then[m] = now[m];

if (flag4 && (now[n] > (then[n] + THRESH))) {
                        digitalWrite(counterPin, HIGH);
                        digitalWrite(13, HIGH);
                        Serial.println ("Someone sat on the bench."); // more debugging
                        flag5 = true;
                      }
                      else { 
                        digitalWrite(counterPin, LOW);
                        digitalWrite(13, LOW);
                      }
                      then[n] = now[n];

if (flag5 && (now[o] > (then[o] + THRESH))) {
                        digitalWrite(counterPin, HIGH);
                        digitalWrite(13, HIGH);
                        Serial.println ("Someone sat on the bench."); // more debugging
                        flag6 = true;
                      }
                      else { 
                        digitalWrite(counterPin, LOW);
                        digitalWrite(13, LOW);
                      }
                      then[o] = now[o];

if (flag6 && (now[p] > (then[p] + THRESH))) {
                        digitalWrite(counterPin, HIGH);
                        digitalWrite(13, HIGH);
                        Serial.println ("Someone sat on the bench."); // more debugging
                        flag7 = true;
                      }
                      else { 
                        digitalWrite(counterPin, LOW);
                        digitalWrite(13, LOW);
                      }
                      then[p] = now[p];

if (flag7 && (now[q] > (then[q] + THRESH))) {
                        digitalWrite(counterPin, HIGH);
                        digitalWrite(13, HIGH);
                        Serial.println ("Someone sat on the bench."); // more debugging
                        flag8 = true;
                      }
                      else { 
                        digitalWrite(counterPin, LOW);
                        digitalWrite(13, LOW);
                      }
                      then[q] = now[q];

if (flag8 && (now[r] > (then[r] + THRESH))) {
                        digitalWrite(counterPin, HIGH);
                        digitalWrite(13, HIGH);
                        Serial.println ("Someone sat on the bench."); // more debugging
                      }
                      else { 
                        digitalWrite(counterPin, LOW);
                        digitalWrite(13, LOW);
                      }
                      then[r] = now[r];

}
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}*
```

The last update is a little confusing -- I'm not sure what you're trying to accomplish there, but maybe I just need to read it a couple more times.

However, from the earlier attempts, I think maybe the problem is the lack of a suitable reference. You're comparing the value to the last reading + 200, which I assume is an arbitrary figure chosen to represent a big enough change in light to be considered a change in occupancy. But then you set the last reading to the current reading and sample again. So, in effect, your reference is constantly moving toward the current value. This is like automatic gain control with no feedback.

Also, the time it takes the Arduino to sample your inputs, write your results to serial, and return back to the beginning of the loop is very short. So, your sliding scale is going to slide very quickly.

What you need is a stable reference with which to compare.

You can dedicate a sensor to ambient light, but then what if someone sitting down casts a shadow on other seats? Maybe your unoccupied seats will be sufficiently below ambient to trigger a false positive.

You could use a calculated window to average the brightest the LDR has seen in the last ... say 30 minutes. But what if someone has been sitting for 45? You're back to where you are now, where the reference is no longer accurate.

Maybe what you need is to detect transitions. Sudden light-to-dark, or dark-to-light. Maybe you would need to sample every 1/4 second, and hold the last two seconds worth of samples. If the value now is significantly different from the value two seconds ago, act on it. Also, consider using percentages rather than a hard-coded value of 200. At night, the system will be worthless, but at least during the morning and evening, where the light may not be high enough to make a 200 unit difference, a change of 25% might still be useful.

                for (int p = 0; p < numberOfSensors != i != j !=k !=l !=m !=n !=o; p++) {
                  now[p] = analogRead(ldr_pins[p]);
                  for (int q = 0; q < numberOfSensors != i != j !=k !=l !=m !=n !=o !=p; q++) {
                    now[q] = analogRead(ldr_pins[q]);
                    for (int r = 0; r < numberOfSensors != i != j !=k !=l !=m !=n !=o !=p !=q; r++) {
                      now[r] = analogRead(ldr_pins[r]);

Now I'm confused.


Here is what I have in mind. It compiles, but I haven't tested because I don't have all those sensors:

const byte numberOfSensors = 10;
const int THRESH = 200; // Threshold value
const byte counterPin = A10; // Counter pin

const byte ldr_pins [numberOfSensors] = { A0, A1, A2, A3, A4, A5, A6, A7, A8, A9};
int now [numberOfSensors] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int then [numberOfSensors] = { 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000};

void setup()
{
  pinMode(counterPin, OUTPUT); //Sets Counter to OUTPUT
  pinMode(13, OUTPUT); //Sets Pin 13 the LED to Output
  Serial.begin(9600);
}  // end of setup

void loop()
  {
  
  // read sensors
  for (int i = 0; i < numberOfSensors; i++)
     now[i] = analogRead(ldr_pins[i]);

  // check each one
  for (int i = 0; i < numberOfSensors; i++)
    {
     // change over threshold?
     if (abs (then [i] - now[i]) > THRESH)
       {
       Serial.print ("Someone ");
       if (now [i] > then [i])
          {
          Serial.print ("sat on");
          digitalWrite(counterPin, HIGH);  // hit counter
          }  
       else
          {
          Serial.print ("got up from");
          }  
       Serial.print (" bench ");
       Serial.println (i);       
       }  // end of over threshold
     
    }  // end of checking each sensor
    
  // remember for next time
  for (int i = 0; i < numberOfSensors; i++)
     then [i] = now [i];
 
  delay (100);  // brief delay
  digitalWrite(counterPin, LOW);
                 
}  // end of loop

!

You can't be that confused, Nick, you just wrote perfect code for the project!

Thank you very much, it now works flawlessly, and I can easily modify every value on testing it outside.

Thanks everybody, too, you've been a massive help on this, my first arduino project, and for helping me catch the Arduino bug.

If there are any niggles or follow up questions on this, this will be where I'll ask them, but for now, I think the post is Solved =)

Thanks again, guys.

I love to see the use of color in wiring up the board. Of course, if the color was not ALL red, it would have been even better.

PaulS:
I love to see the use of color in wiring up the board. Of course, if the color was not ALL red, it would have been even better.

Haha, very true, unfortunately for me, one roll of wire is cheaper than two!

Hi again everybody, sorry to keep finding new areas to explore, but this is pretty addictive.

After reading a little about the EEPROM on the Arduino, and having observed your (Nick) code's elegance in knowing which sensor has been activated, I was wondering if it were feasible to have the EEPROM record the amount of times each sensor was sat on over the period of a day. We will be leaving the Arduino securely locked up inside the bench each day, and can access it in the evening, and it would be lovely to be able to plug it in and read the totals for each LDR's total amount of seats from the EEPROM so we can relay this information to the bench's users. We are interested to see if ambient conditions such as sunlight on one side of the bench, or noise on another will affect people's choice of where to sit on it.

As I understand it, it is possible to write bytes of data to the EEPROM so that it can be accessed at a later date without it needing power, or do you think it is simply easier to have a cumulative total written into the script that prints to the serial monitor so that at the end of the day we can wander down to the bench, plug the arduino in via USB and read off the monitor how many people have sat on each? Printing for example a list of the total amount for each LDR at the end of each loop?

The EEPROM is nice and exciting, but perhaps an easier method is as above?

Thank you, again...

As I understand it, it is possible to write bytes of data to the EEPROM so that it can be accessed at a later date without it needing power

I'll take some of what you're smoking, if you don't mind.

Access to data in EEPROM can occur only if you've programmed the Arduino to provide that access. And, that can only happen if the Arduino has power.

Oh wow, I can see how my syntax has cause this miscommunication. I meant that the EEPROM can store the data after the Arduino loses power - similar to a traditional hard disk.

I have decided that probably the simplest way to count this data though is by using the following few very simple lines of code so that I can view the results just by starting up Serial Monitor and checking each of the LDRs still works at the end of the day, which will be common practice anyway:

Declaring val:

int val [numberOfSensors] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

Creating separate cumulative totals after the 'if' covered in the same breath as operating the counter:

val[i] = val[i] + 1;

And finally printing this information when it changes at the end of the 'for':

      Serial.print ("So far, the amount of people who have sat on seat number ");
      Serial.print (i);
      Serial.print (" is ");
      Serial.println (val[i]);

Easy peasy, and all I have to do i wave my hand over an LDR to check its current cumulative total.

val[i] = val[i] + 1;

Have you ever wondered why the language used to program the Arduino is not called C = C + 1?

Haha, 'The More You Know'.

        val[i] = val[i]++;

Haha, 'The More You Know'.

The more you know you need to learn.

val[i]++;