Cont Rotation Servo - Detect, move, wait function

Hi everyone,

This is my first post so go easy on me :slight_smile:

Before I start I want to add that I’ve scoured youtube and the forums for what I’m trying to do. I’ve learned a lot but not quite what I need.

I’ve been building a small rain awning system and can’t figure out how I get my continuous rotation servo to stop.

Here’s what I’d like my continuous rotation servo to do:
When it senses there is rain, I’d like it to rotate clockwise until the awning is in the open position (will i need an endpoint switch for this?). After the rain stops, I’d like for it to wait 15 minutes and then retract.

Should be super simple, right!?
I don’t have the rain sensor yet so I’m using a temp sensor in the meantime.

I’ve got my code so the temp sensor will sense when the temp is above a certain level and it will start spinning the servo in the right direction. But it just continues to spin until the temp drops again.

How can I get it to do what I stated, above?

Here is my terrible code.

#include <Servo.h>

// Set parameters


float tempC = 0;
float tempF = 0;
Servo motor;

void setup()
{
 Serial.begin(9600);
 sensors.begin();


}

void loop(void)
{ 

 sensors.requestTemperatures();
 tempC = sensors.getTempCByIndex(0);
 tempF = sensors.toFahrenheit(tempC);
 motor.write(90);
 printTemperature();
 

 if (tempF >87.00)
   {
motor.attach(9);  // attaches the servo on pin 9 to a servo object
motor.write(180);
   }
   else
   {
   motor.write(95);
   }

}

void printTemperature()
{

 Serial.print(tempF);
 Serial.print("F");
 Serial.print("\n");
}

Help me Arduino community…you’re my only hope.

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

Should be super simple, right!?

What makes you think that? Below is some servo test code you can experiment with to see different speeds and to find the neutral stop position of your servo (should be near 90 deg or 1500us). Also #7 below about posting code in code boxes.

http://forum.arduino.cc/index.php/topic,148850.0.html

// zoomkat 3-28-14 serial servo incremental test code
// using serial monitor type a character (s to increase or a 
// to decrease) and enter to change servo position 
// (two hands required, one for letter entry and one for enter key)
// use strings like 90x or 1500x for new servo position 
// for IDE 1.0.5 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.

#include<Servo.h>
String readString;
Servo myservo;
int pos=1500; //~neutral value for continous rotation servo
//int pos=90;

void setup()
{
  myservo.attach(7, 400, 2600); //servo control pin, and range if desired
  Serial.begin(9600);
  Serial.println("serial servo incremental test code");
  Serial.println("type a character (s to increase or a to decrease)");
  Serial.println("and enter to change servo position");
  Serial.println("use strings like 90x or 1500x for new servo position");
  Serial.println();
}

void loop()
{
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }
  if (readString.length() >0) {
    if(readString.indexOf('x') >0) { 
      pos = readString.toInt();
    }

    if(readString =="a"){
      (pos=pos-1); //use larger numbers for larger increments
      if(pos<0) (pos=0); //prevent negative number
    }
    if (readString =="s"){
      (pos=pos+1);
    }

    if(pos >= 400) //determine servo write method
    {
      Serial.println(pos);
      myservo.writeMicroseconds(pos);
    }
    else
    {   
      Serial.println(pos);
      myservo.write(pos); 
    }
  }
  readString=""; //empty for next input
}

With a continuous rotation servo you have no control over position and time will be a poor indicator of position because the servo may run faster or slower depending on the load on it. You will need additional switches to detect the open and closed positions.

You will need code that works something like this

void loop() {
  read awningOut switch
  read awningIn switch
  if (rainFalling == true) {
    if (awningOut == false) {
       // set servo to move out
    }
    else {
      // set servo to stop
    }
  }
  else {
    if (15 mins passed) {
      if (awningIn == false) {
         // set servo to move in
      }
      else {
         // set servo to stop
      }
    }
  }
}

...R

I’ve built a rain sensor that I’d like to open and close an awning. (building the miniature version to make sure it all works…that’s why it’s a servo)

I’ve got it to read the rain, then out put a message to the TFT display.
I can even get it to turn the servo on when it senses rain.

I JUST CAN’T GET THE SERVO TO STOP

I’d like for the servo to hit a limit switch OR just run for a set period of time.

it’s a continuous rotation servo

here’s my code.

//SERVO STUFF
#include <Servo.h>
Servo myservo;
int pos = 0;



// TFT PIN INFO
#define sclk 13 //SCL
#define mosi 11 //SDA
#define cs   10 //CS
#define dc   9 //RS/DC
#define rst  8  //RES

// SD CARD SLOT PIN INFO
#define SD_CS    4  // Chip select line for SD card
#define TFT_CS  10  // Chip select line for TFT display
#define TFT_DC   9  // Data/command line for TFT
#define TFT_RST  8  // Reset line for TFT (or connect to +5V)


#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>

#if defined(__SAM3X8E__)
   #undef __FlashStringHelper::F(string_literal)
   #define F(string_literal) string_literal
#endif

Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);
float p = 3.1415926;


//RAIN SENSOR INFO

// lowest and highest sensor readings:
const int sensorMin = 0;     // sensor minimum
const int sensorMax = 1024;  // sensor maximum

void setup() {

 Serial.begin(9600);  
tft.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab
    tft.fillScreen(ST7735_BLACK); // MAKE THE SCREEN BLACK
myservo.attach(2);
 myservo.write(95);
}
void loop() {
 // read the sensor on analog A0:
 int sensorReading = analogRead(A0);
 // map the sensor range (four options):
 // ex: 'long int map(long int, long int, long int, long int, long int)'
 int range = map(sensorReading, sensorMin, sensorMax, 0, 3);
 
 // range value:
 switch (range) {
case 0:    // Sensor getting wet
   Serial.println("It's Raining!");
 tft.fillScreen(ST7735_BLACK);
 tft.setCursor(20, 30);
 tft.setTextSize(2);
 tft.setTextColor(0xF600);
 tft.println("RAIN");
 myservo.write(180);
   break;
case 1:    // Sensor getting wet
   Serial.println("Looks Like Rain");

   break;
case 2:    // Sensor dry - To shut this up delete the " Serial.println("Not Raining"); " below.
   Serial.println("No Rain");
 tft.fillScreen(ST7735_BLACK);
 tft.setCursor(10, 10);
 tft.setTextSize(2);
 tft.setTextColor(0xF100);
 tft.println("NO RAIN");
  myservo.write(95);
   break;
 }
 delay(3000);  // delay between reads
}

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

OK,

I got it to just do the amount of rotations I needed it to do. But now it keeps repeating the step.

Now I’d like to tell it how to detect what state it’s in

something like:

if - already open and it’s raining, do nothing
if - already closed and it’s not raining, do nothing.

here’s my updated code:

// Trying to combine rain sensor with TFT output



//SERVO STUFF
#include <Servo.h>
Servo myservo;
int pos = 0;



// TFT PIN INFO
#define sclk 13 //SCL
#define mosi 11 //SDA
#define cs   10 //CS
#define dc   9 //RS/DC
#define rst  8  //RES

// SD CARD SLOT PIN INFO
#define SD_CS    4  // Chip select line for SD card
#define TFT_CS  10  // Chip select line for TFT display
#define TFT_DC   9  // Data/command line for TFT
#define TFT_RST  8  // Reset line for TFT (or connect to +5V)


#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>

#if defined(__SAM3X8E__)
   #undef __FlashStringHelper::F(string_literal)
   #define F(string_literal) string_literal
#endif

Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);
float p = 3.1415926;


//RAIN SENSOR INFO

// lowest and highest sensor readings:
const int sensorMin = 0;     // sensor minimum
const int sensorMax = 1024;  // sensor maximum

void setup() {

 Serial.begin(9600);  
tft.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab
    tft.fillScreen(ST7735_BLACK); // MAKE THE SCREEN BLACK
myservo.attach(2);
 myservo.write(95);
}
void loop() {
 // read the sensor on analog A0:
 int sensorReading = analogRead(A0);
 // map the sensor range (four options):
 // ex: 'long int map(long int, long int, long int, long int, long int)'
 int range = map(sensorReading, sensorMin, sensorMax, 0, 3);
 
 // range value:
 switch (range) {
case 0:    // Sensor getting wet
   Serial.println("It's Raining!");
 tft.fillScreen(ST7735_BLACK);
 tft.setCursor(20, 30);
 tft.setTextSize(2);
 tft.setTextColor(0xF600);
 tft.println("RAIN");
 myservo.write(180);
 delay(5000);
myservo.write(95);
   break;
case 1:    // Sensor getting wet
   Serial.println("Looks Like Rain");
   delay(3000);

   break;
case 2:    // Sensor dry - To shut this up delete the " Serial.println("Not Raining"); " below.
   Serial.println("No Rain");
 tft.fillScreen(ST7735_BLACK);
 tft.setCursor(10, 10);
 tft.setTextSize(2);
 tft.setTextColor(0xF100);
 tft.println("NO RAIN");
 myservo.write(0);
 delay(5000);
myservo.write(95);
   break;
 }
 delay(3000);  // delay between reads
}

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

something like:

if - already open and it's raining, do nothing if - already closed and it's not raining, do nothing.

So. you need to keep track of the current state. Have you opened the whatever? Have you closed the whatever? Has it changed to raining? Has it changed to not-raining?

You can't make decisions based on changes unless you know what has changed, and you can't know what has changed without storing the previous state. That state change detection example bears investigation.

@eclecticelectric, do not cross-post. Threads merged.