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?
#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;
}
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"
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
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
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
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);
}
}
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?