Go Down

Topic: I couldn't run a servo motor from interrupt. (Read 220 times) previous topic - next topic

yoobibikunn

#15
May 11, 2019, 10:25 am Last Edit: May 11, 2019, 10:33 am by yoobibikunn
OK, clearly you do not understand how to write a program to do what you want to do.

If you can present a properly detailed plan, we can pull from your unfortunate code, the elements needed to do it properly.  :smiley-lol:
The project that I try to do is the smart garden water system, the sensor "https://www.smart-prototyping.com/Soil-Hygrometer-Detection-Module-Soil-Moisture-Sensor-For-Arduino.html" that I use is measuring the humidity in the soil and I want the servo to work if the humidity in the soil is below 5% and the servo motor doesn't work if it is above 50%. I do the value reading from the sensor in the interrupt, I tried to run the servo motor in the loop, but the servo does not work. So my X problem is how I can start and stop the servo suddenly according to the value in the sensor.



Code: [Select]
#include <TimerOne.h>
#include <Servo.h>
#include <EEPROM.h>

Servo servo;

int sensorPin = A0;
int sensorValue = 0;
int percentValue = 0;

int servo_speed = 3000;
bool state = false;
bool servostate = false;

bool direct  = false;
int pos = 0;
int address1 = 0;
int address2 = 1;


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

  servo.attach(6);
  pos = EEPROM.read(address1);
  direct = EEPROM.read(address2);
 
  Timer1.initialize(1000000);
  Timer1.attachInterrupt( timerIsr ); // enable the timer
}


void timerIsr()
{
  Timer1.detachInterrupt();  //stop the timer
  sensorValue = analogRead(sensorPin);
  Serial.print("\n\nAnalog Value: ");
  Serial.println(sensorValue);
  percentValue = map(sensorValue, 1023, 200, 0, 100);
  Serial.print("\nPercentValue: ");
  Serial.print(percentValue);
  Serial.println("%");
 
  if(percentValue > 50)
  {
    servostate = false;
  }
  else if(percentValue < 5)
  {
    servostate = true;
  }
  Timer1.attachInterrupt( timerIsr );  //enable the timer
}

void loop() {
  if(servostate)
  {
      servo.write(pos);
   
      if(pos == 180)
      {
        direct = true;
        EEPROM.write(address2, direct);
      }
      else if (pos == 0)
      {
        direct = false;
        EEPROM.write(address2, direct);
      }
 
      if(direct) pos--;
      else pos++;
     
      EEPROM.write(address1, pos);
 
      delay(servo_speed/180);
  }

}


Im using EEPROM for save servo direct and pos.

I download timer library here -->https://code.google.com/archive/p/arduino-timerone/downloads

Paul__B

OK, here's the situation.

You supposedly know what it is you want to do, but you fail to understand that we do not know what that is because you have not disclosed it.  It is a matter of failed communication.

You continue to use completely nonsensical terms such as "run the servo motor" and "start and stop the servo".  What is this servo motor?  What does it do?  What does "the servo motor doesn't work if it is above 50%" mean?  I begin to wonder if you even know yourself!  :smiley-eek:

You have got yourself wound up with completely irrelevant things such as interrupts and a timer library.  Neither of these is in any way even remotely relevant to your project and posting code which includes them is a waste of everyone's time.

Robin2

To follow from @Paul__B's question in Reply #16 please answer these questions.
  • How often does the soil moisture content need to be checked? (my guess is that two or three times a day would be enough).
  • If the soil is too dry what mechanism do you have to add water to it?
  • How big is the area of soil that you wish to manage?

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Ripcrow

Why are you using an interrupt anyway. The timer should only be used to time when the soil moisture reading is taken. The speed and angle determine the time the servo will move.
I think it should be something like this : read moisture if moisture good do nothing else if moisture bad turn servo ( tap on ) read moisture if moisture good turn servo opposite direction ( tap off) else if moisture bad do nothing ( leave tap on ).
There is no way to trigger an interrupt using software ,it must be done using an input.
If you still need to use interrupt try using a digital write ( high) on a pin example pin 9. Run a wire from pin 9 to your chosen interrupt pin. When you require the interrupt the digitalWrite command on pin 9 will send a high signal to the interrupt pin and trigger the interrupt.

Paul__B

Why are you using an interrupt anyway.
Due to complete ignorance of what an interrupt is in a microcontroller/ computer.  :smiley-eek:

I think it should be something like this : read moisture if moisture good do nothing else if moisture bad turn servo ( tap on ) read moisture if moisture good turn servo opposite direction ( tap off) else if moisture bad do nothing ( leave tap on ).
I am probing for some description of whether the servo is supposed to turn a tap (in which case a little "hobby" servo would not be capable) or whether it must operate a bucket pump (same problem) or what!  :smiley-lol:

If you still need to use interrupt try using a digital write ( high) on a pin example pin 9. Run a wire from pin 9 to your chosen interrupt pin. When you require the interrupt the digitalWrite command on pin 9 will send a high signal to the interrupt pin and trigger the interrupt.
Absolutely, incontestably, no possible use whatsoever for an interrupt.  :smiley-roll:

Go Up