Servo Sweep with conditions

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?

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

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.

#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;
}

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

...and if you think we're being picky, ask yourself "Did I really write my source with italics?"

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"

OK, we're still missing a few things here.
The first is tags, and another is a list of your observations and the output from your debug prints.

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.

//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);                        
                  } 
               }
}

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.

Your servo is being told to go to pos 0 and then move step by step to pos 180

               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

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

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

Mark

holmes4:
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?

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.

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

Which happens in the else block.

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.

         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.

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

//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);                        
    } 
  }
}

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.

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.

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

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

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

I suspect that it is a bit more complicated than that. What I suspect you want is to move the servo to a position, if it is not already there.

High moisture --> Move the servo to 180, if it is not already there
Low moisture --> Move the servo to 0, if it is not already there

So, you need to keep track of where the servo is. Move the servo from where it is, in steps, if a move is needed. Move from currPos to destPos, in steps, rather than from 0 to 180 or from 180 to 0 (assuming that currPos and destPos are the names you define/use). Update currPos after every movement. Set destPos to 0 or 180, if radical movement is needed.

Actually, it seems like you would want to tie the amount to move the servo to the amount that the current sensor reading differs from the desired reading. If the soil is only a tiny bit damp, don't throw the window wide open.

If you only need the servo to move between two positions without speed control, you probably coulds modify the below code to simply move the servo depending on the desired value. You night also need to a deadband to keep the servo from hunting when the input is at the 400 value (if value > 402 or if value < 398).

//zoomkat servo button test 12-29-2011

#include <Servo.h>
int button1 = 4; //button pin, connect to ground to move servo
int press1 = 0;
int button2 = 5; //button pin, connect to ground to move servo
int press2 = 0;
Servo servo1;

void setup()
{
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  servo1.attach(7);
  digitalWrite(4, HIGH); //enable pullups to make pin high
  digitalWrite(5, HIGH); //enable pullups to make pin high
}

void loop()
{
  press1 = digitalRead(button1);
  if (press1 == LOW)
  {
    servo1.write(170);
  }    
  
  press2 = digitalRead(button2);
  if (press2 == LOW)
  {
    servo1.write(10);
  }
}

Thank you for the help, ill test it asap

Edit: well i think im gonna try this

//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 = 440;
const int number2 = 360;

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) {                                 
    myservo.write(179);              
    delay(2000);                       
  } 

  if (analogRead(2) < number2) {                             
    myservo.write(0);               
    delay(2000);                        
  } 

}

So, you need to keep track of where the servo is. Move the servo from where it is, in steps, if a move is needed. Move from currPos to destPos, in steps, rather than from 0 to 180 or from 180 to 0 (assuming that currPos and destPos are the names you define/use). Update currPos after every movement. Set destPos to 0 or 180, if radical movement is needed.

Well you were right, the servo keeps going wild when he reachs some condition. Where i can get a code for something like that? or does anybody know how it would be?