Go Down

Topic: Getting two servos and RGB LED working together (Read 518 times) previous topic - next topic

mik85

Hi there

First I have to say Im new to programming and Arduino 

Im working on a battery box as a school project. The idea is to determine batteries on their weight.

I have RGB LED that is changing color according to the weight and to servos.
First servo opens a flap and the second is pushing the batteries.

The problem is that I can get the LED working but once I uncomment the servo part, the LED won't work as desired. It will only turn red and the servo is working a bit odd too..

I've been stuck in this for days  =(  Hopefully I can get some help here

Thanks in advance


Code: [Select]

/*
There is a **RGB LED** which gets the color GREEN when the device
  is ready for input, YELLOW when it is processing and RED when
  the input is not recognized as a battery.
 
**One infrared sensor** for detecting an incoming object.
 
  **Two servos**. One for opening and closing the flap at the end of the tube.
  The second for turning the bowl on the scale in one or the other direction.
 
  Finally there is a **weight scale** sending information to Arduino in steps 0-1023.
 

*/


const int redPin = 11; // R petal on RGB LED module connected to digital pin 11
const int greenPin = 9; // G petal on RGB LED module connected to digital pin 9
const int bluePin = 10; // B petal on RGB LED module connected to digital pin 10
const int buttonPin1 = 2; // the infrared sensor


int AAAVal,AAVal,CVal,DVal = 0; // used to store battery values
int button1State = 0; // variable for storing the value of the infrared sensor

//#include <Servo.h>
//Servo servo1, servo2;
/*
Creates a servo object to control a servo.
servo1 = flap. servo2 = turning the scale bowl
*/

void setup()
{
         
        Serial.begin(9600); // initialize serial communication at 9600 bits per second:
       
        pinMode(redPin, OUTPUT); // sets the redPin to be an output
        pinMode(greenPin, OUTPUT); // sets the greenPin to be an output
        pinMode(bluePin, OUTPUT); // sets the bluePin to be an output
        pinMode(buttonPin1, INPUT); // the infrared sensor in the final version
         
        //servo1.attach(5); // attaches the servo on pin 5 to the servo object
        //servo2.attach(6); // attaches the servo on pin 6 to the servo object
 
}

void loop()
{
// Ready for input         
       
       
        button1State = digitalRead(buttonPin1); // read the state of the pushbutton/infrared sensor value
        //int servo1Pos = 180; // servo1, flap initial position
        //int servo2Pos = 80;// servo2, initial position
        int sensorValue = analogRead(A0);   // the analog reading (which goes from 0 - 1023) weight measuring
       
       AAAVal = constrain(sensorValue, 50, 200);// weight(step) value of an 'AAA' battery
        AAVal = constrain(sensorValue, 210, 232);// weight(step) value of an 'AA' battery
       CVal = constrain(sensorValue, 243, 289);// weight(step) value of a 'C' battery
        DVal = constrain(sensorValue, 295, 360);// weight(step) value of a 'D' battery
         
        boolean runWeight = false;
       

       
        if (button1State == LOW) // If object passes infrared sensor in the tube
       {
       
        // servo1.write(servo1Pos = 20);// Open flap
        yellow();
        delay (1000);
        runWeight = true;
        //servo1.write(servo1Pos = 90);// Close flap
        //delay (20);
             
       }
        else // If nothing enters the tube
       {
         green();// turn ON green color
       
       
       
       }
           

// Object landing in the bowl!

         
         while (runWeight == true){
         // delay (1500);     
        if (sensorValue == AAAVal)// if object weighs as an AAA battery
       {
       
        Serial.println("AAA battery");
        yellow();delay(1000);
        //servo2.write(servo2Pos = 160);
        delay(20); // delay for 0.2 second(s)
        //servo2.write(servo2Pos = 80);
        //delay(20);
        runWeight = false;
       
       }
       
        else if (sensorValue == AAVal) // if object weighs as an AA battery
       {
        Serial.println("AA battery");
        delay(20);
        runWeight = false; // delay for 1.5s second(s)
        //servo2.write(servo2Pos = 20);
        //delay(1500); // delay for 1.5 second(s)
       }
       
        else if (sensorValue == CVal) // if object weighs as a C battery
       {
        Serial.println("C battery");
        delay (20);
        runWeight = false;
        //servo2.write(servo2Pos = 20);
        //delay(1500); // delay for 1.5 second(s)
       }
       
        else if (sensorValue == DVal) // if object weighs as a D battery
       {
        Serial.println("D battery");
        delay(20);
        runWeight = false;
        //servo2.write(servo2Pos = 20);
        //delay(1500); // delay for 1.5 second(s)
       }
       
        // if there is some load on the scale and weight is not among the defined values
        else if (sensorValue != 0 & sensorValue != 1 & sensorValue != 2)
       
       {
        Serial.println("NOT recognized as a battery");
        red(); // turn the RGB LED Red
        delay (800);
        //servo2.write(servo2Pos = 15); // battery denied
        //delay(500); // delay for 0.5 second(s)
        //servo2.write(servo2Pos = 80);
        //delay(20); // delay for 0.2 second(s)
        runWeight = false;
       
       }
       
        else
       {
        //servo2.write(servo2Pos = 80);
        green(); // when nothing is on the weight, the RGB LED turns green again
        //delay(500);
        runWeight = false;
       
       }
         
 
       
         
}
runWeight = false;
Serial.println(sensorValue);
delay(200);
}

void green(){
// turn ON green color
analogWrite (redPin, 0);
analogWrite (greenPin, 200);
analogWrite (bluePin, 0);
//delay (2000);
}
void blue(){
// turn ON blue color
analogWrite (redPin, 0);
analogWrite (greenPin, 0);
analogWrite (bluePin, 255);

}

void red(){
// turn ON red color
analogWrite (redPin, 255);
analogWrite (greenPin, 0);
analogWrite (bluePin, 0);
//delay (2000);
}

void yellow(){
// turn ON yellow color
analogWrite (redPin, 255);
analogWrite (greenPin, 50);
analogWrite (bluePin, 0);
delay (2000);
}


johnwasser

A servo can draw a significant amount of power.  Perhaps that is what is causing problems?  Do you have a hefty 5-6V power supply for the servos?
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

PaulS

Servos use timers. PWM users timers. There are not enough timers to go around, so using servos means sacrificing PWM capabilities, on some pins.

The first to go are the ones on pins 9 and 10. Use some other PWM pins for your LED.

tuxduino

Hi, just some quick notes.

You update sensorValue just once per loop(), because it's outside the while(runWeight) {} block. I don't see how you can get out of that while() cycle.

I think you got the battery type recognition logic wrong. When working with analoRead() you usually check the value against a range, not for an exact value.

For example (pseudocode):

value = analogRead(0)
if (value >= 100 and value < 200) batteryType = 1
else if (value >= 200 and value < 300) batteryType =2
etc.

PaulS

Code: [Select]
        int sensorValue = analogRead(A0);   // the analog reading (which goes from 0 - 1023) weight measuring
       
       AAAVal = constrain(sensorValue, 50, 200);// weight(step) value of an 'AAA' battery
        AAVal = constrain(sensorValue, 210, 232);// weight(step) value of an 'AA' battery
       CVal = constrain(sensorValue, 243, 289);// weight(step) value of a 'C' battery
        DVal = constrain(sensorValue, 295, 360);// weight(step) value of a 'D' battery

If you are weighing one battery, you can't make decisions about how much 4 different types of batteries weigh. The constrain function is most certainly the wrong thing to be using here.

mik85



Quote
A servo can draw a significant amount of power.  Perhaps that is what is causing problems?  Do you have a hefty 5-6V power supply for the servos?


I have used two microservos which I don't think are using that much power. But even without them attached physically, the program won't work as intended..

Quote
Servos use timers. PWM users timers. There are not enough timers to go around, so using servos means sacrificing PWM capabilities, on some pins.

The first to go are the ones on pins 9 and 10. Use some other PWM pins for your LED.

I am not sure I understand how PWM uses timers and there is not enough timers to go around. How is that?  but I will follow your advice and use other PWM pins for the LED.

Quote
You update sensorValue just once per loop(), because it's outside the while(runWeight) {} block. I don't see how you can get out of that while() cycle.

My intention was that once there is no weight on the scale this will happen
Code: [Select]
else
       {
        //servo2.write(servo2Pos = 80);
        green(); // when nothing is on the weight, the RGB LED turns green again
        //delay(500);
        runWeight = false;
       
       }

and runWeight will be set to false, therefore breaking the while cycle. But this might not be the best solution..!?


Thanks for your replies guys  :)  Now I will try out some of the changes and keep you posted


tuxduino

If you don't update sensorValue and repeat the battery type detection code, I don't see how runWeight can change its value (this is just a suggestion, I might be wrong...)

Did I already tell you you should use CTRL-T and use empty lines in a sensible manner ? Trust me, it greatly helps writing understandable (and unbuggy) code.

:)

PaulS

Quote
I am not sure I understand how PWM uses timers

PWM turns pins on and off very quickly, to simulate a variable voltage output. That toggling happens when a timer interrupt happens, and the PWM-set interrupt handler says it's time.

Quote
and there is not enough timers to go around.

Compromises need to be made. An unlimited number of timers (one per pin) just isn't practical.


Go Up