encoder

I think that helps a lot, lets see if my understanding is correct.

Items moving on a conveyer need to be sorted by weight.
There are a range of solenoids that can select an item and each solenoid is intended for a particular range of weights.

An encoder generates pulses in proportion to the movement of the conveyer. There is a specific number of pulses to indicate the distance from the weight detector to the location of each solenoid.

The task is to weigh the moving items and activate the solenoid appropriate to each items weight when it is over that particular solenoid.

Does that match what you want to do?

If so, then there are a few more details to clarify before you should start writing your sketch.

-What is the maximum number of items that will be on the conveyer between the weighing point and the solenoid furthest away from that point? (your sketch needs to keep track of the weights for all of these)

-How many solenoids will you have?

-Do you know how many pulses there will be from the weighing point to the first solenoid?

-Do you know how many pulses between solenoids ? (are the solenoids equally spaced?)

-Does the time to activate a solenoid depend on conveyer speed? (does the speed change?)

Items moving on a conveyer need to be sorted by weight.
There are a range of solenoids that can select an item and each solenoid is intended for a particular range of weights.

An encoder generates pulses in proportion to the movement of the conveyer. There is a specific number of pulses to indicate the distance from the weight detector to the location of each solenoid.

The task is to weigh the moving items and activate the solenoid appropriate to each items weight when it is over that particular solenoid.

Does that match what you want to do?

Exactly!!!

The maximum number of items(fruits or cups) will be 20pcs(from the weighing point to the furthest solenoid) and I hope i could have more than 10 solenoids.
Since my encoder's resolution is 512 per revolution, i think the pulses from the weighing point to the first solenoid would be approximately, 5,120(10 revolutions).
The solenoids are equally spaced to each other. Approximately, 3072(6 revolutions).
i hope the solenoids' activation time could be proportional to the conveyer speed.

Can you expand on this.

LED is blinked on #13 pin after encoder rotate 512 steps. but this is because it has sensed HIGH state after encoder rotated above 512 steps in advance.

And have you tried this:-

val = digitalRead(3);  
if ((val == HIGH) && (encoder0Pos > (startCount + 512)))  
{
 startCount = encoder0Pos;        
 digitalWrite(13, HIGH);    
 delay(1000); 
 digitalWrite(13, LOW); 
}

I suspect the use of delay might be a problem, it's good for holding the pin high, but it is pausing the whole loop, but, I'll need to see if I'm understanding the problem correctly first.

There are many ways of implementing your application. Here is one idea for a design, let me know if this makes sense to you and if you want any help understanding and implementing it.

If you can adjust the physical distance of the weighing device so that it is the same distance from the first solenoid as the solenoids are from each other then that makes the design simpler. We can add in functionality later to cope with a different distance if necessary but my explanation will be easier if we assume that the weight sensor and the solenoids are all separated by 3072 counts.

Assume ten solenoids numbered from 1 to 10 with number 1 being the one for the lightest objects and 10 for the heaviest.

Lets refer to every 3072 counts as a cycle. For each cycle (3072 counts) we want to weigh an item that is over the weight sensor and activate a solenoid when an item weighed in an earlier cycle comes over the correct solenoid.

A cycle has a duration in counts, this duration starts at the time an object is near enough that a solenoid should be activated, and it finishes when the solenoid is deactivated. The actual timings will depend on how long the solenoid needs activating in order to ensure the object drops. You also want to make sure that you are taking your weight value a point in the cycle that the object is fully over the weight sensor.

If I was building this for commercial use I would be tempted to use a photo transistor to detect the physical presence of the objects (or whatever is holding the objects) to trigger the start and end of a cycle, but this may be more complex then you need. So to keep it simpler for now, say a new cycle starts every 3072 counts and lasts for enough counts for an object to drop.

At each cycle I would get the weight value. If the value was greater than a threshold I would use a lookup table or calculate the appropriate solenoid number for this weight. For example, no object would return a value of 0 (no solenoid), the lightest objects would return solenoid 1 etc. with the heaviest object returng 10.

I would then have a circular buffer, you can google circular buffers if you are not familiar with this, but for now think of it as a kind of shift register that holds integer values. We will put the solenoid number we just calculated at the first available position in this buffer. At each new cycle, the appropriate solenoid number (or 0 if no object) would put into the next position in the buffer.

here is an example where we assume that obj1 has weight value of 2, obj2 has value of 1, and obj3 has value of 3

At the start, the first cycle with an object above the weight threshold will look like this
obj3 obj2 obj1 ? ? ?
weight Sol1 Sol2 SoL3

and if obj1 has a weight value of 2 then immediately after weighing the buffer will look like this:
[2] [0] [0] ?.

Here is the second cycle:
Obj4 obj3 obj2 obj1 ? ?
weight Sol1 Sol2 SoL3

buffer after cycle 2: [1] [2] [0] [0] ?.

And the third cycle:
Obj5 Obj4 obj3 obj2 obj1 ?
weight Sol1 Sol2 SoL3

buffer after cycle 3: [3] [1] [2] [0] [0] ?.

Now the trick is to remember that at the start of every cycle the first element of this circular buffer is always over the weighing sensor, the second is always over solenoid 1. the third over two etc. So all that needs to be done is to check if the value in each buffer position from 1 to 10 (remember in C that the first position is 0) is the same as the solenoid number. In every case that the value equals the position then that solenoid should be activated.

Because we need a circular buffer (memory is finite on the arduino so we need to reuse elements of the buffer that represent objects that have been dropped, the current position wraps around when it gets to the end of the buffer. But I think all this is easier to implement then it is to explain.

That's a lot to take in. Does it make any sense to you?

thank you. yes, they all make sense. I think if i use photo transistor to detect the object above solenoid, the solenoid will trigger every object over itself even though the object is not corresponding to its position. so i thought encoder will solve this problem. is there any other way to use photo transistor while avoiding this?
also, another aspect that should be put under consideration is that the objects which will be going through the weighing system won't be all differ in terms of weight. some of them(which are same weight) are infeeded in serial, not positioned in an order of different weight. so, if the first object is weight to be 200g and the second object also happends to be 200g then, there must be some solution to cope with for both data of the same objects.
as you've mentioned, calculating the appropriate solenoid for a certain weight is the best way to pull this off.

Object weight order should not matter for the above logic to work. Objects can all be the same weight or any random mix of weights from minimum to maximum. What does matter is the ability to know when an object of known weight appears over a particular solenoid.

We know how far apart the solenoids are (they are one cycle apart, which is 3072 counts). So if we know when a particular object is over the first solenoid then we also know that it will be over the second in the next cycle, over the one after that in the following cycle etc.

The challenge is knowing when a specific object that has been weighed arrives over the solenoids. An easy way to do this is if the objects can carried on the conveyer so they are the exactly the same space apart as the solenoids. Its not essential but I think it may be a little easier to implement the sketch if this is the case. Can your conveyer be constructed so the objects are carried the same distance apart as the solenoid spacing?

Can you expand on this.

LED is blinked on #13 pin after encoder rotate 512 steps. but this is because it has sensed HIGH state after encoder rotated above 512 steps in advance.

And have you tried this:-

val = digitalRead(3);  

if ((val == HIGH) && (encoder0Pos > (startCount + 512)))  
{
startCount = encoder0Pos;        
digitalWrite(13, HIGH);    
delay(1000);
digitalWrite(13, LOW);
}



I suspect the use of delay might be a problem, it's good for holding the pin high, but it is pausing the whole loop, but, I'll need to see if I'm understanding the problem correctly first.

thank you.
I just tried your suggestion. but it is the same result that i am having at the moment. i first have to rotate encoder until 512 steps before i provide voltage variable to analoginput.
i hope i could reverse such result. If i provide a certain voltage variable temporarily(through a quick rotation of the potentiameter) to arduino, i hope the receiption of voltage variable act like an internal switch in arduino sketch so that arduino's 13th digital pin get HIGH after encoder rotate for 512 counts.

I hope the following code will be not too far from what you want, but I have thrown it together really fast so not only has it not been tested, I am pretty sure it will need fixing in a few places to get it to work correctly. You probably will need to put lots of debug serial.print statemens in various places to see whats going on. I hope it helps. good luck!

#define encoder0PinA  2
#define encoder0PinB  3  // this was 4
#define  firstSolenoidPin 4                                
#define  numberOfSolenoids  10   //note that solenoid 10 will be pin 14 which is analog pin 0
#define weightPin           5    // weight sensor to be connected to analog pin 5 (was pin 0, but this is used above)
#define numberOfCycles  (numberOfSolenoids + 1) // one cycle for each solenoid position plus one for the weight position


#define CountsPerCycle  3072   //adjust this so its the number of counts to get an object from entering proximity of one soleniod to the next
                               // it should also be the count to get from the center of the weight sensor to the first solenoid
                               
volatile int encoder0Pos = 0;  // this can be an int because we only need to count up to 3072 (its signed just in case the belt ever runs backwards)
unsigned int CycleCount = 0;   // this is the current cycle count  

int ObjectBuffer[numberOfCycles ] = {0};  // this used to make a circular buffer holding the appropriate solenoid for each object
int tail = 0;      // index to the next avalailable space in the above buffer

void setup()                        
{
  for(int i=0; i < numberOfSolenoids; i++)
     pinMode( i + firstSolenoidPin, OUTPUT);
  pinMode(encoder0PinA, INPUT); 
  digitalWrite(encoder0PinA, HIGH);       
  pinMode(encoder0PinB, INPUT); 
  digitalWrite(encoder0PinB, HIGH);       
  attachInterrupt(0, doEncoder, CHANGE);  
  Serial.begin (9600);
  Serial.println("start");                
}

void activateSolenoid(int solenoid){
    digitalWrite(firstSolenoidPin + solenoid -1 , HIGH);  
}

void  deactivateSolenoids() {   
 for(int i = 0; i < numberOfSolenoids; i++)
    digitalWrite( firstSolenoidPin + i, LOW);   
}         
      
int getSolenoidFromWeight( int weight){
   int  solenoid;
  
   solenoid = 0;
   if( weight > 1) 
      solenoid =  1 + ( weight / 110);  // this gives a  solenoid number from 1 to 10
                 // replace this code with a table or formula that sorts as you require
   if(solenoid > 10)
      solenoid = 10;
  return solenoid;    
}

void objectQueAdd(int requiredCycles){     // store the number of cycles to the correct solenoid for the object now being weighed

  int t;
  t = tail;
  ObjectBuffer[t] = requiredCycles;
  if (++t >= numberOfCycles ){  //wrap around if buffer capacity has been exceeded
     t = 0;
     tail = t;        
   }    
}

int objectQueGet(int index){     // return the solenoid number appropriate for the object stored at this location 
   int target = (index + tail) %  numberOfCycles;
  return  ObjectBuffer[target];  
}

int objectQueDebug(){
// you may want to write a temporary debug function here to print all values in the buffer starting from the tail. Dont forget you need to wrap (see the two functions above for some ideas on how to do that)
}

void ProcessCycle(int weight) {
  int requiredCycles =  getSolenoidFromWeight(weight);  // this is the solenoid number to be activated when the object currently being weighed
    // is over that solenoid. Because of the way we have spaced everthing,
    // this will happen in exactly requiredCycles from now.
   objectQueAdd( requiredCycles);    // save this value in our circular buffer
   for(int i = 1; i <= numberOfSolenoids; i++){
     if(objectQueGet(i) == i) 
         activateSolenoid(i);  // triger solenoid becuase the correct weight is over it  
   }
   delay(100);  // all appropriate solenoids have been activated so wait for objects to drop    
   deactivateSolenoids();    // deactivate solenoids  
}

void loop(){
  cli();      //disable interrupts
  if(encoder0Pos >= CountsPerCycle){  
      encoder0Pos = 0;  // reset the count
      sei();             // enable interrupts
      int weightVal = analogRead(weightPin) ;       
      ProcessCycle(weightVal);       
   } 
   else 
      sei();   // make sure interrupts are enabled
 }

void doEncoder(){
  if (digitalRead(encoder0PinA) == HIGH) {   
    if (digitalRead(encoder0PinB) == LOW) {  
      // encoder is turning
      encoder0Pos = encoder0Pos - 1;         
    } 
    else {
      encoder0Pos = encoder0Pos + 1;         
    }
  }
  else                                        
  { 
    if (digitalRead(encoder0PinB) == LOW) {   
      
      encoder0Pos = encoder0Pos + 1;          
    } 
    else {
      encoder0Pos = encoder0Pos - 1;          
    }

  }     
}

Thank you very much. After testing, i shall get back to you.

I just had a read through the code I posted and noticed that there was a second call to reset the encoder count. I have edited the code to remove it.

I guess there will be a few other things you will need to do to get this to work. Feel free to ask for clarification of anything that is not clear. And you would be well served to put Serial.print statements in key areas so you can see how the data in the buffer is managed.

excellent!! thank you very much for your help, mem. it's highly appreciated.

No problem.

I am looking forward to seeing the output of the debugging code you will probably need to add to show the values in the buffer at each of the positions. If you print these starting from the tail then position 0 (i.e. the value at the tail) corresponds to the physical position over the weight sensor, position 1 (i.e. the next after the tail) is over the first solenoid, position 2 over the second and so on. And of course the values in the buffer are the correct solenoids for each objects weight.

Have fun.

how are you, mem? I've came up with below scketch. could you please check whether it's logical enough?
i think many part of this scketch became not logical as i've tried and put more.
i couldn't compile this sketch in arduino environment.
but, your original scketch compiled smoothly as silk.
i've assigned digital pins as solenoidpins from #4 to #14(analog pin).

#define encoder0PinA  2
#define encoder0PinB  3  
#define firstSolenoidPin 4      
#define secondSolenoidPin 5      
#define thirdSolenoidPin 6      
#define forthSolenoidPin 7      
#define fifthSolenoidPin 8      
#define sixthSolenoidPin 9      
#define seventhSolenoidPin 10      
#define eighthSolenoidPin 11      
#define ninthSolenoidPin 12      
#define tenthSolenoidPin 13                          
#define eleventhfSolenoidPin 14   
#define weightPin 5    
#define numberOfCycles  (numberOfSolenoids + 1) 
#define CountsPerCycle  3072   
                               
volatile int encoder0Pos = 0;  
unsigned int CycleCount = 0;   

int ObjectBuffer[numberOfCycles ] = {0};  
int tail = 0;      // index to the next avalailable space in the above buffer


void setup()                        
{
  for(int i=0; i < numberOfSolenoids; i++)
     pinMode( i + firstSolenoidPin, OUTPUT);
  pinMode(encoder0PinA, INPUT); 
  digitalWrite(encoder0PinA, HIGH);       
  pinMode(encoder0PinB, INPUT); 
  digitalWrite(encoder0PinB, HIGH);       
  attachInterrupt(0, doEncoder, CHANGE);  
  Serial.begin (9600);
  Serial.println("start");                
}

void activateSolenoid(int solenoid){
    digitalWrite(firstSolenoidPin + solenoid -1 , HIGH);  
}

void  deactivateSolenoids() {   
 for(int i = 0; i < numberOfSolenoids; i++)
    digitalWrite( firstSolenoidPin + i, LOW);   
}         
      
int getSolenoidFromWeight( int weight){
   int  solenoid;
  
   solenoid = 0;
   if( weight > 20) 
      solenoid = 1 + ( weight / 110);  
                    
   if(solenoid > 25)
      solenoid = 2 + ( weight / 110);

   if(solenoid > 30)
      solenoid = 3 + ( weight / 110);

   if(solenoid > 35)
      solenoid = 4 + ( weight / 110);

   if(solenoid > 40)
      solenoid = 5 + ( weight / 110);

   if(solenoid > 45)
      solenoid = 6 + ( weight / 110);

   if(solenoid > 50)
      solenoid = 7 + ( weight / 110);

   if(solenoid > 55)
      solenoid = 8 + ( weight / 110);

   if(solenoid > 60)
      solenoid = 9 + ( weight / 110);

   if(solenoid > 65)
      solenoid = 10 + ( weight / 110);

   if(solenoid > 70)
      solenoid = 11 + ( weight / 110);

     return solenoid;    
}

void objectQueAdd(int requiredCycles){     

  int t;
  t = tail;
  ObjectBuffer[t] = requiredCycles;
  if (++t >= numberOfCycles ){  //wrap around if buffer capacity has been exceeded
     t = 0;
     tail = t;        
   }  
   Serial.print(tail, DEC)  
}

int objectQueGet(int index){      
   int target = (index + tail) %  numberOfCycles;
  return  ObjectBuffer[target];  
}

int objectQueDebug(){
 Serial.println (ObjectBuffer, DEC);

}

void ProcessCycle(int weight) {
  int requiredCycles =  getSolenoidFromWeight(weight);  
    
   objectQueAdd( requiredCycles);    
   for(int i = 1; i <= numberOfSolenoids; i++){
     if(objectQueGet(i) == i) 
         activateSolenoid(i);    
   }
   delay(100);     
   deactivateSolenoids();    solenoids  
}

void loop(){
  cli();      
  if(encoder0Pos >= CountsPerCycle){  
      encoder0Pos = 0;  
      sei();             
      int weightVal = analogRead(weightPin) ;       
      ProcessCycle(weightVal);       
   } 
   else 
      sei();   
 }

void doEncoder(){
  if (digitalRead(encoder0PinA) == HIGH) {   
    if (digitalRead(encoder0PinB) == LOW) {  
      
      encoder0Pos = encoder0Pos - 1;         
    } 
    else {
      encoder0Pos = encoder0Pos + 1;         
    }
  }
  else                                        
  { 
    if (digitalRead(encoder0PinB) == LOW) {   
      
      encoder0Pos = encoder0Pos + 1;          
    } 
    else {
      encoder0Pos = encoder0Pos - 1;          
    }

  }     
  Serial.println (encoder0Pos, DEC);          
}

I have fixed the syntax errors. The main problem was the sketch was missing a definition for numberOfSolenoids.

The logic in getSolenoidFromWeight() was not correct. I have fixed it for the first few solenoids but you need to add in the missing solenoids. here is an explination of the logic:

if the weight is under 1 that means there is no object so there is no solenoid so we set the value to 0
the 'else if' statmeents mean that only the first one that is true will be executed so we test from the lower weights to the higher weights. for example, if a weight is 23 then the if logic will work as follows:

if( weight < 1) //will be false, the weight is not less than 1

else if( weight < 20) //will be false, the weight is not less than 20 (I assume a sensor value of 20 or more is a reading where the object weight is too high for the solenoid 1 so it will be selected by a later solenoid)

else if(weight < 25) // will be true, 23 is less than 25 so the solenoid will be set to 2
solenoid = 2 ;
else if(weight < 30) // this and all the following statements will not be executed because 'else if' means only do this if the previous stament was false

Hope that helps.

#define encoder0PinA  2
#define encoder0PinB  3  
#define firstSolenoidPin 4      
#define secondSolenoidPin 5      
#define thirdSolenoidPin 6      
#define forthSolenoidPin 7      
#define fifthSolenoidPin 8      
#define sixthSolenoidPin 9      
#define seventhSolenoidPin 10      
#define eighthSolenoidPin 11      
#define ninthSolenoidPin 12      
#define tenthSolenoidPin 13                          
#define eleventhfSolenoidPin 14   
#define numberOfSolenoids 11
#define weightPin 5    
#define numberOfCycles  (numberOfSolenoids + 1) 
#define CountsPerCycle  3072   
                               
volatile int encoder0Pos = 0;  
unsigned int CycleCount = 0;   

int ObjectBuffer[numberOfCycles ] = {0};  
int tail = 0;      // index to the next avalailable space in the above buffer


void setup()                        
{
  for(int i=0; i < numberOfSolenoids; i++)
     pinMode( i + firstSolenoidPin, OUTPUT);
  pinMode(encoder0PinA, INPUT); 
  digitalWrite(encoder0PinA, HIGH);       
  pinMode(encoder0PinB, INPUT); 
  digitalWrite(encoder0PinB, HIGH);       
  attachInterrupt(0, doEncoder, CHANGE);  
  Serial.begin (9600);
  Serial.println("start");                
}

void activateSolenoid(int solenoid){
    digitalWrite(firstSolenoidPin + solenoid -1 , HIGH);  
}

void  deactivateSolenoids() {   
 for(int i = 0; i < numberOfSolenoids; i++)
    digitalWrite( firstSolenoidPin + i, LOW);   
}         
      
int getSolenoidFromWeight( int weight){
   int  solenoid;
  
   if( weight < 1)
       solenoid = 0;
   else if( weight < 20) 
      solenoid = 1;                      
   else if(weight < 25)
      solenoid = 2 ;
   else if(weight < 30)
      solenoid = 3;
   else if(weight > 35)
      solenoid = 4;
   else if(weight < 40)
      solenoid = 5;
 // YOU NEED TO PUT SIMILAR STATMENTS FOR SOLENOIDS 6 TO 10 
   else if(weight < 70)
      solenoid = 11;

   if(solenoid > numberOfSolenoids)
      solenoid = numberOfSolenoids;

   return solenoid;    
}

void objectQueAdd(int requiredCycles){     

  int t;
  t = tail;
  ObjectBuffer[t] = requiredCycles;
  if (++t >= numberOfCycles ){  //wrap around if buffer capacity has been exceeded
     t = 0;
     tail = t;        
   }  
   Serial.print(tail, DEC);  
}

int objectQueGet(int index){      
   int target = (index + tail) %  numberOfCycles;
  return  ObjectBuffer[target];  
}

int objectQueDebug(){
 for(int i=0; i < numberOfCycles; i++) {  
   Serial.print (ObjectBuffer[i], DEC);
   Serial.print (","); 
 }   
 Serial.println();

}

void ProcessCycle(int weight) {
  int requiredCycles =  getSolenoidFromWeight(weight);  
    
   objectQueAdd( requiredCycles);    
   for(int i = 1; i <= numberOfSolenoids; i++){
     if(objectQueGet(i) == i) 
         activateSolenoid(i);    
   }
   delay(100);     
   deactivateSolenoids();   
}

void loop(){
  cli();      
  if(encoder0Pos >= CountsPerCycle){  
      encoder0Pos = 0;  
      sei();             
      int weightVal = analogRead(weightPin) ;       
      ProcessCycle(weightVal);       
   } 
   else 
      sei();   
 }

void doEncoder(){
  if (digitalRead(encoder0PinA) == HIGH) {   
    if (digitalRead(encoder0PinB) == LOW) {  
      
      encoder0Pos = encoder0Pos - 1;         
    } 
    else {
      encoder0Pos = encoder0Pos + 1;         
    }
  }
  else                                        
  { 
    if (digitalRead(encoder0PinB) == LOW) {   
      
      encoder0Pos = encoder0Pos + 1;          
    } 
    else {
      encoder0Pos = encoder0Pos - 1;          
    }

  }     
  Serial.println (encoder0Pos, DEC);          
}

Lets get some debug code in there.

In the function ProcessCycle(int weight)

Put the following immediately after the line objectQueAdd( requiredCycles);
objectQueDebug();

this will print the status of the buffer to the serial terminal. Do a test run to get a few dozen lines of the debug output then cut it from the terminal window and paste the text here. Don't bother taking a picture, the raw debug output text posted here will be easier to work with.

Lets get some debug code in there...
Do a test run to get a few dozen lines of the debug output then cut it from the terminal window and paste the text here. Don't bother taking a picture, the raw debug output text posted here will be easier to work with.

Could you do a run with 'Serial.println (encoder0Pos, DEC);' commented out or removed from doEncoder so we can just see what happens when the count reaches 3072.

Also, replace the Serial.print statement in objectQueAdd with the following:
Serial.print("adding ");
Serial.print(requiredCycles);
Serial.print("at tail pos: ");
Serial.println(tail, DEC);

Please paste the actual debug text into a reply here so I can work with it in my text editor.

i replaced the Serial.print statement in objectQueAdd with the Serial.prints you've mentioned.
I removed 'Serial.println (encoder0Pos, DEC); from doEncoder and did a test run and i've got the following result.
start
adding0at tail pos: 00,0,0,0,0,0,0,0,0,0,0,0, ------ all the numbers are "0" if there is no object on the loadcell
adding0at tail pos: 00,0,0,0,0,0,0,0,0,0,0,0,
adding4at tail pos: 04,0,0,0,0,0,0,0,0,0,0,0, ------ when I put 100g object, 4 appeared after 3072
adding4at tail pos: 04,0,0,0,0,0,0,0,0,0,0,0,
adding4at tail pos: 04,0,0,0,0,0,0,0,0,0,0,0, ------ I left the 100g object until this point
adding0at tail pos: 00,0,0,0,0,0,0,0,0,0,0,0, ------ I removed the 100g object from the loadcell
adding2at tail pos: 02,0,0,0,0,0,0,0,0,0,0,0, ------ I put 28g object and 2 appeared
adding0at tail pos: 00,0,0,0,0,0,0,0,0,0,0,0, ------ I removed the object from the loadcell
adding4at tail pos: 04,0,0,0,0,0,0,0,0,0,0,0, ------ i put on 100g object
adding2at tail pos: 02,0,0,0,0,0,0,0,0,0,0,0, ------ i stoped rotating the encoder and changed the 100g object with 28g object.

I used the following weight criteria.

  if( weight < 1)
       solenoid = 0;
   else if( weight < 5) 
      solenoid = 1;                      
   else if(weight < 10)
      solenoid = 2 ;
   else if(weight < 15)
      solenoid = 3;
   else if(weight > 20)
      solenoid = 4;
   else if(weight < 25)
      solenoid = 5;
   else if(weight < 30)
        solenoid = 6;
   else if(weight < 35)
        solenoid = 7;
   else if(weight < 40)
        solenoid = 8;
   else if(weight < 45)
        solenoid = 9;
   else if(weight < 50)
        solenoid = 10;
   else if(weight < 55)
      solenoid = 11;

In your sketch, replace all the code in objectQueAdd with the following:

void objectQueAdd(int requiredCycles){ 
  int t;
  t = tail;
  ObjectBuffer[t] = requiredCycles;
  if (++t >= numberOfCycles ){  //wrap around if buffer capacity has been exceeded
     t = 0;  
   }  
   tail = t;        // bug: this line was in the if statement so tail was never updated
   Serial.print("Adding "); 
   Serial.print(requiredCycles); 
   Serial.print(" at tail pos: "); 
   Serial.println(tail, DEC);    // make sure your version uses println on this line (not print)
}

The bug was the line: tail=t; was in the wrong place so tail was never being updated.

ok, i changed the sketch according to your advise, and this is the result i've got.
as you know, the below resuts are appeared when the encoder reaches to each 3072 step point.

start

adding0at tail pos: 1      --------------  there is nothing on loadcell as encoder rotates
0,0,0,0,0,0,0,0,0,0,0,0,

adding0at tail pos: 2      
0,0,0,0,0,0,0,0,0,0,0,0,

adding0at tail pos: 3     --------------- i put nothing on the loadcell until here
0,0,0,0,0,0,0,0,0,0,0,0,

adding4at tail pos: 4     --------------- i put 100g object on the loadcell 
0,0,0,4,0,0,0,0,0,0,0,0,

adding4at tail pos: 5
0,0,0,4,4,0,0,0,0,0,0,0,

adding4at tail pos: 6    ---------------- i left 100g object on the loadcell until here
0,0,0,4,4,4,0,0,0,0,0,0,

adding0at tail pos: 7    ---------------- i removed the object
0,0,0,4,4,4,0,0,0,0,0,0,

adding0at tail pos: 8    ---------------- i put nothing on the loadcell
0,0,0,4,4,4,0,0,0,0,0,0,

adding0at tail pos: 9    
0,0,0,4,4,4,0,0,0,0,0,0,

adding0at tail pos: 10  ----------------- i put nothing until here
0,0,0,4,4,4,0,0,0,0,0,0,

adding2at tail pos: 11  ----------------- i put 28g object on the loadcell
0,0,0,4,4,4,0,0,0,0,2,0,

adding2at tail pos: 0    ----------------- i left 28g object until here
0,0,0,4,4,4,0,0,0,0,2,2,

adding0at tail pos: 1   ----------------- i removed the object
0,0,0,4,4,4,0,0,0,0,2,2,

adding4at tail pos: 2   ------------------ i put 100g object again
0,4,0,4,4,4,0,0,0,0,2,2,

adding4at tail pos: 3   ------------------ i put 500g object on the loadcell
0,4,4,4,4,4,0,0,0,0,2,2,

adding0at tail pos: 4  ------------------- i removed the 500g object
0,4,4,0,4,4,0,0,0,0,2,2,

start     ------------- I had another trial from here

adding0at tail pos: 1    --------------- i put nothing
0,0,0,0,0,0,0,0,0,0,0,0,

adding4at tail pos: 2    ----------------  put 500g object on the loadcell
0,4,0,0,0,0,0,0,0,0,0,0,

adding4at tail pos: 3    ----------------kept 500g object on the loadcell
0,4,4,0,0,0,0,0,0,0,0,0,

adding0at tail pos: 4    --------------- i removed 500g object
0,4,4,0,0,0,0,0,0,0,0,0,

That's better.

Lets do a test where after a few cycles you just put one 100 gram object on.

What you should see is the number 4 moving down the circular buffer. After 12 cycles the numbers should all be 0 again.

Then do a similar test but after one object of 100 grams, put the 28 gram object on next.
You should see a 4 moving down the buffer followed by the two.

Oh, before you try this, make a small change in the debug in objectQueAdd, move all the print statements so they are all immediately after the statement: t = tail;
you may also check your sketch has spaces in this statement: Serial.print(" at tail pos: ");

If the output is as expected we can move on to check the solenoid activation logic.