spencerkim:
Do you mean servo.attach ?
If that was a question about reply #55 then the answer is no
spencerkim:
Do you mean servo.attach ?
If that was a question about reply #55 then the answer is no
Then, what do you mean by servo sweep
spencerkim:
Then, what do you mean by servo sweep
Look in the example programs for the Servo library. One of them is named Sweep. Does your servo move as expected when you upload the program ?
Yes, the sweep program in the servo library works. Should I try by making the servo motor loop at 89 and 90 degrees when the water is sensed in the water sensor? Would that work?
#include <Servo.h> //include servo library
Servo myservo; //define servo as servo
byte waterSens[] = {A1, A3};
const byte howManySensors = sizeof(waterSens) / sizeof(waterSens[0]);
int servoPos = 0;
void setup()
{
Serial.begin(9600);
Serial.println("https://forum.arduino.cc/index.php?topic=641224");
myservo.attach(2);//attach servo to pin 2
Serial.print("Number of sensors "); Serial.println(howManySensors);
Serial.println("setup() done");
delay(1000);
}
void loop() {
int sensorValue = analogRead(waterSens);//read the water sensor value
sensorValue = map(sensorValue, 0, 1023, 0, 90);
if (sensorValue >= 1) {
for (servoPos = 0; servoPos <= 90; servoPos += 1) { // goes from 0 degrees to 90 degrees
// in steps of 1 degree
myservo.write(servoPos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for (servoPos = 90; servoPos >= 89; servoPos -= 1) { // goes from 90 degrees to 89 degrees
myservo.write(servoPos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}
else{
myservo.write(0);
}
Serial.println(sensorValue);
delay(20);
}
Or, would this be a better code to make the servo motor to stay near 90 degrees?
spencerkim:
#include <Servo.h> //include servo library
Servo myservo; //define servo as servo
byte waterSens[] = {A1, A3};
const byte howManySensors = sizeof(waterSens) / sizeof(waterSens[0]);
int servoPos = 0;
void setup()
{
Serial.begin(9600);
Serial.println("[MERGED] [MERGED] Coding 5 water sensors and one servo - Project Guidance - Arduino Forum");
myservo.attach(2);//attach servo to pin 2
Serial.print("Number of sensors "); Serial.println(howManySensors);
Serial.println("setup() done");
delay(1000);
}
void loop() {
int sensorValue = analogRead(waterSens);//read the water sensor value
sensorValue = map(sensorValue, 0, 1023, 0, 90);
if (sensorValue >= 1) {
for (servoPos = 0; servoPos <= 90; servoPos += 1) { // goes from 0 degrees to 90 degrees
// in steps of 1 degree
myservo.write(servoPos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for (servoPos = 90; servoPos >= 89; servoPos -= 1) { // goes from 90 degrees to 89 degrees
myservo.write(servoPos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}
else{
myservo.write(0);
}
Serial.println(sensorValue);
delay(20);
}
Or, would this be a better code to make the servo motor to stay near 90 degrees?
You have:
byte waterSens[] = {A1, A3};
.
.
.
int sensorValue = analogRead(waterSens);
waterSens is a pointer to an array of bytes. You need to access the element there with something like:
int sensorValue = analogRead(waterSens[0]);
This will read the sensor on A1. If you want to interleave the sensors you need a variable as an index.
So, if I want to also do it for A3, I need to set the variable of the sensorvalue as an index?
To read A3:
int sensorValue = analogRead(waterSens[1]);
1 is the index in the []. See the array reference.
Does this come close to what you want (compiles, not tested):
#include <Servo.h> //include servo library
#define MOISTURE_THRESH 450 //ADC counts base moisture level (you fill in correct value)
#define HYST 20 //ADC counts +/- from this value will switch
#define SAMPLE_INTERVAL 50 //mS mS between sensor checks
#define WET_POS 90 //
#define DRY_POS 0 //
Servo myservo; //define servo as servo
byte
waterSens[] = {A1, A3};
const byte
howManySensors = sizeof(waterSens) / sizeof(waterSens[0]);
int
grReadings[howManySensors];
void setup()
{
Serial.begin( 9600 );
Serial.println( "https://forum.arduino.cc/index.php?topic=641224" );
myservo.attach( 2 );//attach servo to pin 2
myservo.write( 0 );
Serial.print( "Number of sensors " ); Serial.println( howManySensors );
Serial.println( "setup() done" );
}//setup
void loop()
{
unsigned long
tNow;
static unsigned long
tSample = 0;
static byte
lastbWater = 0,
bWater = 0;
tNow = millis();
if( tNow - tSample >= SAMPLE_INTERVAL )
{
tSample = tNow;
for( int i=0; i<howManySensors; i++ )
{
int sensorValue = analogRead( waterSens[i] ); //read each twice twice due to channel change each pass
delayMicroseconds( 20 );
grReadings[i] = analogRead( waterSens[i] );
}//for
if( bWater == 0 )
{
for( int i=0; i<howManySensors; i++ )
bWater |= (grReadings[i] >= MOISTURE_THRESH+HYST) ? 1:0;
}//if
else
{
byte bDry = 0;
for( int i=0; i<howManySensors; i++ )
bDry |= (grReadings[i] > MOISTURE_THRESH-HYST) ? 1:0;
bWater = bDry;
}//else
if( bWater != lastbWater )
{
lastbWater = bWater;
myservo.write( (bWater) ? WET_POS : DRY_POS );
}//if
}//if
}//loop
5 pages in, I decided to have a further look at the OPs original code from over 2 weeks ago.
I don't have the OP's sensors, but analog is analog, so with potentiometers on A0, A1 and A2, and a servo on pin 9, I tested the OP's code as fixed in my 2 bullets above, and it works. (At least according to my understanding of what's supposed to happen: all sensors dry servo goes one way, at least one sensor is wet, it goes the other?)
Here's OP's code from Nov 2, fixed as in the bullets above (all changes commented) and tested successfully with pots on A0, A1 and A2 and with a servo on 9.
Note the servo positions and threshold for my test:
const byte servoDryPos = 70;
const byte servoWetPos = 110;
const int sensorWetThreshold = 450;
#include <Servo.h> //include servo library
Servo myservo; //define servo as servo
byte waterSens[] = {A0, A1, A2};
const byte howManySensors = sizeof(waterSens) / sizeof(waterSens[0]);
int servoPos;
const byte servoDryPos = 70; //
const byte servoWetPos = 110; //
const int sensorWetThreshold = 450; //
void setup()
{
Serial.begin(9600);
Serial.println("https://forum.arduino.cc/index.php?topic=641224");
myservo.attach(9);//attach servo to pin 9
//also just going to use led13 as a signal
pinMode(LED_BUILTIN, OUTPUT);
Serial.print("Number of sensors "); Serial.println(howManySensors);
Serial.println("setup() done");
delay(1000);
}
void loop()
{
setTheServo(readTheSensors());
delay(500);
}
bool readTheSensors()
{
int currentSensorVal;
bool result = true; //start assuming all dry, if any one (or more) is wet then set false
for (int i = 0; i < howManySensors; i++)
{
currentSensorVal = analogRead(waterSens[i]);
Serial.print(currentSensorVal); Serial.print(" ");
if (currentSensorVal > sensorWetThreshold)
{
result = false;
break;
}
}
if (result)
{
Serial.println("All dry");
//servoPos = 0; // was missing ;
// but have //'d out the above line anyway
// no point having a setTheServo() function AND doing it here
} //this was missing
else
{ //new
Serial.println("At least one sensor is wet"); //was missing ;
// { this { should be on the line before the serial print
//servoPos = 90; // was missing ;
// but have //'d out the above line anyway
// no point having a setTheServo() function AND doing it here
}
return result;
}//readTheSensors()
void setTheServo(bool dry)
{
if (dry)
{
myservo.write(servoDryPos);
digitalWrite(LED_BUILTIN, LOW);
}
else
{
myservo.write(servoWetPos);
digitalWrite(LED_BUILTIN, HIGH);
}
}
Yes, the two codes are close to the one that I want. For the second code, I have tried it already, but it didn't work very well. The servo motor didn't turn when at least one sensor was dry.
spencerkim:
The servo motor didn't turn when at least one sensor was dry.
The way I understood it (but I haven't read every single word in the thread, I must say) if ALL sensors are dry the servo is supposed to go one way, and if AT LEAST one is wet, it goes the other.
Where did "at least one sensor was dry" come from? (Maybe I missed that part...)
Your opening post says:
spencerkim:
I want the servo motor to turn 90 degrees whenever water is detected at one or more of the three water level sensors and the servo motor should come back to the starting position when water is not detected.
... and that's what your code as fixed does, if dry is under the threshold and wet is over. (Although the servo positions I used were 70 and 110 I think.)
sayHovis:
The way I understood it (but I haven't read every single word in the thread, I must say) if ALL sensors are dry the servo is supposed to go one way, and if AT LEAST one is wet, it goes the other.Where did "at least one sensor was dry" come from? (Maybe I missed that part...)
For that part, I meant to say when at least one sensor was wet
spencerkim:
For that part, I meant to say when at least one sensor was wet
Ok well that's what that code does for me, admittedly without your sensors but using a potentiometer on the basis that an analog signal from a pot is the same as one from an analog sensor, and just comparing to some threshold.
If I start with all 3 below the threshold, I get the message they're all dry, servo one side, led off. If one goes over, servo swings, led goes on, message says at least one is wet. If I make another one go over it obviously stays like that. Then only goes back to dry state when both go dry.
Sorry, can't help any more. On my system, it's doing as you ask.....
Thanks for the help. I will try to do it on my system
Did you actually pour water onto the sensor? My monitor is telling me that it is dry the whole time
I told you I don't have your sensors: I used a potentiometer to mimic your sensors to just give a varying value for the analogRead().
sayHovis:
... admittedly without your sensors but using a potentiometer on the basis that an analog signal from a pot is the same as one from an analog sensor, and just comparing to some threshold.
I certainly was not going to order some sensors that I will never use again, just to test your code.
Let's step back and check if any of your sensors work. Forget the servo stuff for a moment: do you have a simple sketch that reads one of your sensors and gives a different value between it being wet and dry?
Just this in loop() should do the trick:
void loop()
{
Serial.println(analogRead(A0));
delay(100);
}
What values do you get as you move a sensor in and out of a glass of water like this guy who going by your image in #22/23 has the same sensor.
If all you're doing is checking the presence or absence of water rather than the depth then perhaps the threshold needs to be set very low? Totally dry, out of the water, would be 0 maybe, but just touching the surface might be 1 or 2, I don't know.
You need to guarantee the sensors are working and that you know what threshold value you actually need.
Where did this 450 come from?
const int sensorWetThreshold = 450;
Since an analogRead() goes from 0-1023 that would presumably be the sensor about half-way in water? Did you test that value or just chose it randomly?
So do everyone a favour (not least yourself ), forget the code you have so far, and just print out the values from the sensor as described.
I got the whole thing to work by setting the threshold to 10. Thanks for the help
spencerkim:
I got the whole thing to work by setting the threshold to 10.
Excellent. Now it might be a good idea to go back to the opening post and edit the title there and add [solved] or similar. (Not that this question is about programming a servo it's about reading an analog sensor and setting its go/no-go threshold.)
edit.. I just looked at your older threads from October, which are presumably on the same project. Back then you had this:
if (sensorValue >= 50) {
It's a pity you didn't stick with a low value like that, since your code in this thread was basically ok all along, just a bad threshold. But all's well that ends well, I guess.
spencerkim:
Thanks for the help
You're welcome.