Program stops working over time.

I have rather simple program where photo cells are used to trigger MIDI notes when light drops under the threshold - person blocking the light.
In order to compensate differences of ambient light I added pots to set the threshold at specific location(different rooms). However I have a dedicated strong light source for the setup.
Something is not quit right - the program stops reacting normally after some time(ambient light change?). Like it works perfectly - then after some time or change of ambient light it either triggers notes all the time without human interaction or does not do a thing - regardless of tweaking the threshold pots..
Could someone check this out?

#include <MIDI.h>
byte note = 0;
byte b = 3;  //-b that slight change will not affect
byte c = 1;

int val1Pin = 0;  //analog pin 0-3 photocell
int val2Pin = 1;
int val3Pin = 2;
int val4Pin = 3;
int val1;        //photocell reads
int val2;
int val3;
int val4;

int val5Pin = 8;  //analog pin 8-11 pot for treshold
int val6Pin = 9;
int val7Pin = 10;
int val8Pin = 11;

int a1 = 0;        // a1-a5 treshold adjustable with pot
int a2 = 0;
int a3 = 0;
int a4 = 0;





 
  
void setup() {

  Serial.begin(31250);   // set MIDI baud rate
  MIDI.sendProgramChange (121,c);  // set MIDI instrument
 
  
}

void loop() {
 
  val1 = analogRead(val1Pin);
    a1 = analogRead(val5Pin);
  if (val1 <= a1-b) {          //if val is under the threshold play notes
  MIDI.sendNoteOn(54,127,c);
delay(300);
  MIDI.sendNoteOn(58,127,c);
  delay(300);
  MIDI.sendNoteOn(66,127,c);
  delay(100);
MIDI.sendNoteOff(54,0,c);
MIDI.sendNoteOff(58,0,c);
MIDI.sendNoteOff(66,0,c); 
      }

     val2 = analogRead(val2Pin);
     a2 = analogRead(val6Pin);
  if (val2 <= a2-b) { 
  MIDI.sendNoteOn(68,127,c);
  delay(100);
  MIDI.sendNoteOn(70,127,c);
  delay(100);
  MIDI.sendNoteOn(73,127,c);
  delay(100);
  MIDI.sendNoteOn(75,127,c);
  delay(100);
MIDI.sendNoteOff(68,0,c);
MIDI.sendNoteOff(70,0,c);
MIDI.sendNoteOff(73,0,c);
MIDI.sendNoteOff(75,0,c);
  }
  
      val3 = analogRead(val3Pin);
      a3 = analogRead(val7Pin);
  if (val3 <= a3-b) {
  MIDI.sendNoteOn(60,127,c);
  delay(200);
  MIDI.sendNoteOn(70,127,c);
  delay(100);
  MIDI.sendNoteOn(68,127,c);
  delay(100);
  MIDI.sendNoteOn(51,127,c);
  delay(300);
  MIDI.sendNoteOn(60,127,c);
  delay(100);
  MIDI.sendNoteOff(60,0,c);
MIDI.sendNoteOff(70,0,c);
MIDI.sendNoteOff(68,0,c);
MIDI.sendNoteOff(51,0,c);
MIDI.sendNoteOff(60,0,c);
  
  }
  
   
     val4 = analogRead(val4Pin);
     a4 = analogRead(val8Pin);
  if (val4 <= a4-b) { 
  MIDI.sendNoteOn(44,127,c);
  delay(300);
  MIDI.sendNoteOn(51,127,c);
  delay(300);
  MIDI.sendNoteOn(49,127,c);
  delay(100); 
 MIDI.sendNoteOff(44,0,c);
MIDI.sendNoteOff(51,0,c);
MIDI.sendNoteOff(49,0,c); 
      }
       
  }

Well ambient light will change in your room depending on the time of the day and you are comparing with a fixed potentiometer threshold - so as conditions change you would need to adjust the pots continuously. (or do you have no window and control lighting yourself?)

Also - are you using "photo cells" like real solar cell (photovoltaic cell)? photovoltaic cells are known to vary their output depending on the heat of the cell -> When a solar cell is heated, it becomes less efficient. for a solar panel it does not change too much and they work even when warm, but for what you measure it can have an impact. would be worth checking.

side note:

you are not initializing the MIDI instance (MIDI_CREATE_DEFAULT_INSTANCE) etc. I'm not an expert with that library and I know that if you know what you do that can work - but are you sure all is set up the right way?

Also instead of using

  if (val1 <= a1-b) {          //if val is under the threshold play notes

you actually might want to map val1 and a1 into a similar space to offset effects at the low and high end of the range. Reading from analog pins (assuming MEGA) might not be very precise if you don't have a very clean Voltage reference.

int val5Pin = 8;  //analog pin 8-11 pot for treshold
int val6Pin = 9;
int val7Pin = 10;
int val8Pin = 11;

Can I assume that you are using a Mega ?

Yes, this setup is with Mega. Code is written some years ago with Arduino(alpha) 0023.
When I check cells with monitor I get readings with light - about 800-900; light blocked - 100-300. The range where it should work is rather large 300-800, so when threshold is set to 500 everything should work even if light or voltage fluctuates somewhat.
And MIDI part works fine.
I have not coded anything for some time and I never was any good with it. After Arduino v.1 with new libraries and such i got totally lost.

Rather than use a potentiometer to set a threshold why not use another photocell to provide a baseline indication of the ambient light level.

...R

I would tend to address this with a pair of low-pass filters.

float slowLo;
float fastLo;

// this funcion is called every 10th of a second
void checkLight() {
  int reading = analogRead(sensorPin);

  slowLo = slowLo * .975 + reading*.025;
  fastLo = fastLo * .75 + reading*.25;

  if(slowLo - fastLo > THRESHOLD) {
    // movement has occured
  }
}

Some experimentation needed, of course. You have a value that reacts slowly to changes in light, and one that reacts quickly. You look at the difference between these to detect transient fluctuations.

To make it act consistently, it's important to throttle the rate at which samples are taken to a known interval: "if it's been 1/10th of a second since I took a sample, then take another sample".

It's easy enough to model the effect of the chosen values using excel, and that can help tune things.

I am sure it is something to do with the EU.

Have you checked if it has signed the "Working time directive"

Oh do come on a ittle levity never hurt anyone!

You mean a French CPU affiliated with an extreme left wing Union? Then goes on strike ?

May be :slight_smile:

It always amazes me that UK employees should sneer at Trades Unions in France who want to improve the pay and conditions of their members. Have UK employees become completely subservient?

...R

well it's not a political blog so will be my last comment on this but if

Trades Unions in France who want to improve the pay and conditions of their members

was the true motivation of the unions, then you could argue there is a grand vision there to be proud of...

The challenge and naked truth at the moment is that unions like CGT actually only have 2,6% of the french workers affiliated and they make a huge mess. Only 8% or french workers are in a Union, compared to 55% in Belgium or 82% in Island... So Unions do no represent anything besides their own political interests and survival.

</political and non technical opinion>