Pages: [1] 2   Go Down
Author Topic: Servo Sweep with conditions  (Read 702 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hello, this part of the code doesn't work and i dont get why.
threshold2 is 70
Simple Servo sweep code

int analogValue2 = dht_dat[0];
                if (analogValue2 > threshold2) {
                for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees
                {                                  // in steps of 1 degree
                  myservo.write(pos);              // tell servo to go to position in variable 'pos'
                  delay(15);                       // waits 15ms for the servo to reach the position
                }
                }
                else {
                for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
                {                               
                myservo.write(pos);              // tell servo to go to position in variable 'pos'
                delay(15);                       // waits 15ms for the servo to reach the position
                  }
               }

Im trying to compare AnalogValue2 and when is over 70 it SHOULD made the servo move from 0 to 180 and when is LOWER than 70 return to 0. What im doing wrong?



Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not enough code, where do you set dht_dat[0] ?   Are you sure it is set? toss some debug print outs in your code right above
Quote
int analogValue2 = dht_dat[0];
.   It is a simple if statement they only fail when the conditions are not met, which leads back to my 1st question.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
#define dht_dpin 14
#define LIGHT_SENSOR_PIN 1
#include <LiquidCrystal.h>

LiquidCrystal lcd(0, 1, 2, 3, 4, 5);

byte bGlobalErr; //for passing error code back from complex functions.
byte dht_dat[4]; //Array to hold the bytes sent from sensor.
int light_intensity = 0;
unsigned int flip = 0;

const int ledPin = 12;       // RELE    pin that the LED is attached to
const int threshold = 400;   // an arbitrary threshold level that's in the range of the analog input

const int threshold2 = 70;   // SERVO    an arbitrary threshold level that's in the range of the analog input

#include <Servo.h>
Servo myservo;  // create servo object to control a servo
                // a maximum of eight servo objects can be created
int pos = 0;

void setup(){
        myservo.attach(9);
        pinMode(ledPin, OUTPUT);
        pinMode(13, OUTPUT);
        lcd.begin(16, 2);
        lcd.print("MTC cia ltda");
        InitDHT(); //Do what's necessary to prepare for reading DHT
        //Serial.begin(9600);
        delay(300); //Let system settle
        //Serial.println("Humidity and temperature\n\n");
        delay(700); //Wait rest of 1000ms recommended delay before
        //accessing sensor
} //end "setup()"

void loop(){
        
        Serial.print("Moisture Sensor Value:");
   Serial.println(analogRead(2));  
   delay(100);
if ( flip & 1 )
        {
                digitalWrite(13, HIGH);
        } else {
                digitalWrite(13, LOW);
        }

        flip++;

        light_intensity=analogRead(LIGHT_SENSOR_PIN);

        ReadDHT();
        switch (bGlobalErr) {
        case 0:
                lcd.setCursor(0, 0);
                // Serial.print("humdity = ");
                lcd.print("T Aire =       ");
                lcd.setCursor(9, 0);
                lcd.print( dht_dat[2], DEC);
                lcd.setCursor(0, 1);
                //Every 7 out of 15 times we show humidity, rest temp
                if ((flip % 15) > 7 )
                {
                        lcd.print("H Aire =      ");
                        lcd.setCursor(9, 1);
                        lcd.print( dht_dat[0], DEC);
                        lcd.setCursor (11,1);
                        lcd.print("%");
                } else {
                        lcd.print("H Suelo =      ");
                        lcd.setCursor(10, 1);
                        lcd.print( analogRead(2), DEC);
                        lcd.setCursor(12,1);
                        lcd.print("%");
                }
                //Serial.print("temperature = ");
                //Serial.print(dht_dat[2], DEC);
                //Serial.print(".");
                //Serial.print(dht_dat[3], DEC);
                //Serial.println("C  ");
                break;
                
        case 1:
                //Serial.println("Error 1: DHT start condition 1 not met.");
                break;
        case 2:
                //Serial.println("Error 2: DHT start condition 2 not met.");
                break;
        case 3:
                //Serial.println("Error 3: DHT checksum error.");
                break;
        default:
                //Serial.println("Error: Unrecognized code encountered.");
                break;
        } //end "switch"
        
        
        int analogValue = analogRead(2);
                // if the analog value is high enough, turn on the LED:
                if (analogValue > threshold) {
                digitalWrite(ledPin, LOW);
                }
                else {
                digitalWrite(ledPin,HIGH);
                }
                
         int analogValue2 = dht_dat[0];
                if (analogValue2 > threshold2) {
                for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees
                {                                  // in steps of 1 degree
                  myservo.write(pos);              // tell servo to go to position in variable 'pos'
                  delay(15);                       // waits 15ms for the servo to reach the position
                }
                }
                else {
                for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
                {                                
                myservo.write(pos);              // tell servo to go to position in variable 'pos'
                delay(15);                       // waits 15ms for the servo to reach the position
                  }
               }


        delay(800); //Don't try to access too frequently... in theory
        //should be once per two seconds, fastest,
        //but seems to work after 0.8 second.
        
} // end loop()

/*Below here: Only "black box" elements which can just be plugged unchanged
   unchanged into programs. Provide InitDHT() and ReadDHT(), and a function
   one of them uses.*/

void InitDHT(){
        //DDRC |= _BV(dht_PIN);//set data pin... for now... as output
        //DDRC is data direction register for pins A0-5 are on
        //PORTC |= _BV(dht_PIN);//Set line high
        //PORTC relates to the pins A0-5 are on.
        //Alternative code...
//        if (dht_dpin-14 != dht_PIN){Serial.println("ERROR- dht_dpin must be 14 more than dht_PIN");};//end InitDHT
        pinMode(dht_dpin,OUTPUT); // replaces DDRC... as long as dht_dpin=14->19
        digitalWrite(dht_dpin,HIGH); //Replaces PORTC |= if dht_pin=14->19
} //end InitDHT

void ReadDHT(){
/*Uses global variables dht_dat[0-4], and bGlobalErr to pass
   "answer" back. bGlobalErr=0 if read went okay.
   Depends on global dht_PIN for where to look for sensor.*/
        bGlobalErr=0;
        byte dht_in;
        byte i;
        // Send "start read and report" command to sensor....
        // First: pull-down i/o pin for 18ms
        digitalWrite(dht_dpin,LOW); //Was: PORTC &= ~_BV(dht_PIN);
        delay(18);
        delayMicroseconds(600);//TKB, frm Quine at Arduino forum
/*aosong.com datasheet for DHT22 says pin should be low at least
   500us. I infer it can be low longer without any]
   penalty apart from making "read sensor" process take
   longer. */
//Next line: Brings line high again,
//   second step in giving "start read..." command
        digitalWrite(dht_dpin,HIGH); //Was: PORTC |= _BV(dht_PIN);
        delayMicroseconds(40); //DHT22 datasheet says host should
        //keep line high 20-40us, then watch for sensor taking line
        //low. That low should last 80us. Acknowledges "start read
        //and report" command.

//Next: Change Arduino pin to an input, to
//watch for the 80us low explained a moment ago.
        pinMode(dht_dpin,INPUT); //Was: DDRC &= ~_BV(dht_PIN);
        delayMicroseconds(40);

        dht_in=digitalRead(dht_dpin); //Was: dht_in = PINC & _BV(dht_PIN);

        if(dht_in) {
                bGlobalErr=1; //Was: Serial.println("dht11 start condition 1 not met");
                return;
        } //end "if..."
        delayMicroseconds(80);

        dht_in=digitalRead(dht_dpin); //Was: dht_in = PINC & _BV(dht_PIN);

        if(!dht_in) {
                bGlobalErr=2; //Was: Serial.println("dht11 start condition 2 not met");
                return;
        } //end "if..."

/*After 80us low, the line should be taken high for 80us by the
   sensor. The low following that high is the start of the first
   bit of the forty to come. The routine "read_dht_dat()"
   expects to be called with the system already into this low.*/
        delayMicroseconds(70);
//now ready for data reception... pick up the 5 bytes coming from
//   the sensor
        for (i=0; i<5; i++)
                dht_dat[i] = read_dht_dat();

//Next: restore pin to output duties
        pinMode(dht_dpin,OUTPUT); //Was: DDRC |= _BV(dht_PIN);
//N.B.: Using DDRC put restrictions on value of dht_pin

//Next: Make data line high again, as output from Arduino
        digitalWrite(dht_dpin,HIGH); //Was: PORTC |= _BV(dht_PIN);
//N.B.: Using PORTC put restrictions on value of dht_pin

//Next see if data received consistent with checksum received
        byte dht_check_sum =
                dht_dat[0]+dht_dat[1]+dht_dat[2]+dht_dat[3];
/*Condition in following "if" says "if fifth byte from sensor
       not the same as the sum of the first four..."*/
        if(dht_dat[4]!= dht_check_sum)
        {bGlobalErr=3; } //Was: Serial.println("DHT11 checksum error");
}; //end ReadDHT()

byte read_dht_dat(){

        byte i = 0;
        byte result=0;
        for(i=0; i< 8; i++) {
                delayMicroseconds(30);

                
                if (digitalRead(dht_dpin)==HIGH) //Was: if(PINC & _BV(dht_PIN))
                        result |=(1<<(7-i));  // "add" (not just addition) the 1
                while (digitalRead(dht_dpin)==HIGH) ;  //Was: while((PINC & _BV(dht_PIN)));
                
                
        }
        return result;
}
« Last Edit: November 24, 2012, 08:14:50 am by eclipsear » Logged

California
Offline Offline
Faraday Member
**
Karma: 82
Posts: 3123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Read through #6 on the Read this before posting a programming question thread.
Logged

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

...and if you think we're being picky, ask yourself "Did I really write my source with italics?"
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.

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

well i said the servo need to move from 0 degree to 180 when the Air humidity is over 70% (dht_dat[0]) and return from 180 or stay in 0...  This mean actually a "Window opening because the humidity is too high"
Logged

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

OK, we're still missing a few things here.
The first is [code] [/code] tags, and another is a list of your observations and the output from your debug prints.
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.

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey everyone, i have this soil sensor OBSoil + sweep servo. In this code the servo should be acting when Analogread(2) > 400 making the servo move from 0 degree to 180 degree and when is lower (else) return from 180 to 0 degree or just stay in 0 degree. (acting like a window)

When I try this code the servo it just acting back and forth.. i think its something with the FOR line in the servo, i tried to make the comparation there but it doesnt work.

This is the basic sweep servo code but im pretty sure its something with the FOR of the servo and the IF that im trying to put there.

Code:
//OB SOIL
//# the sensor value description
//  # 0  ~300      dry soil
//  # 300~700     humid soil
//  # 700~950     in water
#include <Servo.h>
Servo myservo;
const int number = 400;
int pos = 0;

void setup(){
        Serial.begin(9600);
        myservo.attach(9);
}

void loop(){
         Serial.print("Moisture Sensor Value:");
         Serial.println(analogRead(2));  
         delay(100);
         int analogValue2 = analogRead(2);
                if (analogValue2 > number) {
                for(pos = 0; pos < 180; pos += 1)  
                {                                  
                  myservo.write(pos);              
                  delay(15);                      
                }
                }
                else {
                for(pos = 180; pos>=1; pos-=1)    
                {                                
                myservo.write(pos);              
                delay(15);                        
                  }
               }
}
« Last Edit: November 24, 2012, 07:42:07 am by eclipsear » Logged

0
Offline Offline
Shannon Member
****
Karma: 159
Posts: 10409
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You need hysteresis in your code to prevent noise being amplified like this.

You use two threshold values that are far enough apart that sensor noise won't trigger changes.

Lets imagine your sensor has +/-10 counts or so of noise, you might choose thresholds of 390 an 410.

I the value goes above 410 then you move the servo, but only move it back if it falls below 390,

Also you can reduce the noise with low-pass filtering (soil doesn't change very fast does it?).  Keep a running average of the sensor values over a timescale of a minute or so - this should average away most of the noise and allow much more narrow hysteresis limits.
Logged

[ I won't respond to messages, use the forum please ]

Poole, Dorset, UK
Offline Offline
Edison Member
*
Karma: 25
Posts: 1872
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your servo is being told to go to pos 0 and then move step by step to pos 180
Code:
              for(pos = 0; pos < 180; pos += 1)  
                {                                  
                  myservo.write(pos);              
                  delay(15);                      
                }
            

this tells your servo to go to pos 180 and then move step by step to pos 0

Code:
               for(pos = 180; pos>=1; pos-=1)    
                {                                
                myservo.write(pos);              
                delay(15);                        
                  }

So what ever reading you get it just move back forth!


Mark
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So what ever reading you get it just move back forth!
Thank you, thats the big problem for me.. what i should change for making to act like a window? the for should i change it for some other sentence?
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 547
Posts: 45954
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Your servo is being told to go to pos 0 and then move step by step to pos 180
Which happens in a if block.

Quote
this tells your servo to go to pos 180 and then move step by step to pos 0
Which happens in the else block.

Quote
So what ever reading you get it just move back forth!
Not true.

@OP:
You need to put each { on a new line, and use Tools + Auto Format to properly/consistently indent your code. Then, you need to add some Serial.print() and Serial.println() statements to print out the values read from the sensor.

Code:
         Serial.println(analogRead(2)); 
         delay(100);
         int analogValue2 = analogRead(2);
The value that you are printing is NOT the value that you are acting on. While they should be relatively close to the same value, that is true only if your sensor is working correctly. Why not make life easy, though, and print the value that you make decisions on?

Also, you are the only one that can see the output you are getting now, so you are the only one that can solve the problem. Share the output (after you fix it) and the modified code if you want us to help.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok i added the auto format and the }. The problem is when the sensor is lower than 400 is making the servo act like the IF but it should be Else (lower than 400) .. from 0 to 180 degree step by step, returning to 0 fast and going to 0 to 180 degree step by step again and again.

Serial says this and its fine because is not in the soil (making the condition Else < 400 BUT acting like the IF)
Moisture Sensor Value: 0
Moisture Sensor Value: 0
Moisture Sensor Value: 7
Moisture Sensor Value: 7
Moisture Sensor Value: 11
Moisture Sensor Value: 7
Moisture Sensor Value: 0


Code:
//OB SOIL
//# the sensor value description
//  # 0  ~300      dry soil
//  # 300~700     humid soil
//  # 700~950     in water
#include <Servo.h>
Servo myservo;
const int number = 400;
int pos = 0;

void setup()
 {
  Serial.begin(9600);
  myservo.attach(9);
 }

void loop()
{
  Serial.print("Moisture Sensor Value:");
  Serial.println(analogRead(2)); 
  delay(100);
  if (analogRead(2) > number)
  {
    for(pos = 0; pos < 180; pos += 1) 
    {                                   
      myservo.write(pos);             
      delay(15);                       
    }
  }
  else
  {
    for(pos = 180; pos>=1; pos-=1)     
    {                               
      myservo.write(pos);               
      delay(15);                       
    }
  }
}
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 547
Posts: 45954
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The problem is when the sensor is lower than 400 is making the servo act like the IF but it should be Else (lower than 400) .. from 0 to 180 degree step by step, returning to 0 fast and going to 0 to 180 degree step by step again and again.
When the value is less than 400, as it always appears to be, you tell the servo to move from 180 to 0 slowly. But, the servo is not at 180, so, first, it need to go there. Then, it can go to 0 slowly.

Add two more print() statements, one in the if block, and one in the else block.
Code:
Serial.println("Soil is wet"); // in the if block
Serial.println("Soil is dry"); // in the else block

Does the correct message get printed, matching the sensor value? If so, the correct block is being executed.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

umm yeah i think is not the sweep servo i should be using.. i just need to move from position 0 to 1 and from 1 to 0 with conditions

Code:
pos1 = 180 degree
pos0 = 0 degree

if Analogread(2) > 400
 move the servo to pos1
else
 move the servo to pos0

i need a hand for this.. it would be simple as that
Logged

Pages: [1] 2   Go Up
Jump to: