This is a bit weird, and I don't understand anything.
Basically, I'm just playing with my servo. I wrote a small program, which can be found at this link: https://pastebin.pl/view/8e9c9573 (Note: It's three files, I left some comments there, and the idk
function is just my last resort, trying to separate myself from loop
, I really don't know :/ ).
So I run controller.Setup()
in the setup
function, and then in loop I just move it to 180 and detach it, then I run into an infinite loop. Note: I know it's not very good code, but that's not what concerns me right now.
The problem is, when I add the call to detach (line 22), the previous move doesn't run! I think I'm going crazy, cause as soon as I remove the line and recompile, it actually moves.
I tried to remove the lock(Controller::m_Attached)
, and it still doesn't work. Please let me know if I didn't notice something, but I really don't understand.
Notes:
- I'm using
arduino-cli
, here's my not-very-perfect Makefile: https://pastebin.pl/view/daa852ff - I use the Servo library: https://www.arduino.cc/reference/en/libraries/servo/
- I'm using an Arduino Uno
EDIT: Someone told me to post the code in the question, so here I go:
//Main.ino
#include <Servo.h>
#include "Controller.h"
Controller controller(3);
void idk();
void setup() {
Serial.begin(9600);
controller.Setup();
}
void loop() {
idk();
while(true);
}
void idk() {
controller.Move(180);
controller.Unlock();
}
// Controller.h
#pragma once
#include <Servo.h>
class Controller
{
public:
Controller(int servoPin)
: m_ServoPin(servoPin), m_Attached(false) {}
void Setup();
void Move(int angle);
void Lock();
void Unlock();
private:
Servo m_Servo;
bool m_Attached;
const int m_ServoPin = 3;
};
// Controller.ino
#include "Controller.h"
void Controller::Setup()
{
m_Servo.attach(m_ServoPin);
m_Attached = true;
Serial.print("[CONTROLLER] Attached Servo\n");
}
void Controller::Move(int angle)
{
if (m_Attached)
m_Servo.write(angle);
}
void Controller::Lock() {
m_Servo.attach(m_ServoPin);
m_Attached = true;
}
void Controller::Unlock() {
m_Servo.detach();
m_Attached = false;
}
-
the detach() function probably stops the data pin from outputting the servo control signal ... you are disabling the control signal a few microseconds after you enable it, so it is never generated ... furthermore, a servo requires the signal to be present at all timesjsotola– jsotola2020年10月14日 17:02:05 +00:00Commented Oct 14, 2020 at 17:02
-
@jsotola Thank you sooo much. When I add a delay in between the function calls it works. You should make it an answer so that I can accept itstfn– stfn2020年10月14日 17:13:54 +00:00Commented Oct 14, 2020 at 17:13
2 Answers 2
The detach() function probably stops the data pin from outputting the servo control signal.
Your code disables the control signal a few microseconds after it is enabled.
The cotrol signal is never generated.
Furthermore, a servo requires the signal to be present at all times for it to keep its position.
When your programming includes real-world events, you have to think about the time frame of the events, and about the time frame of the running program.
Think in the terms that the program can loop 100,000 times before the servo has finished moving.
Attach and Detach do little except intialise or deintialise variable in the servo library functions and may move the servo to a central position.
The function needs to know which pin to use to drive the servo. Once the servo is attached when you do a servo.write it will send a pulse to the pin. You could do this yourself
int servopin=8;
pinMode (servopin, OUTPUT);
digitalWrite(sevopin,LOW); // makes sure there is no pulse yet
// more code
digitalWrite(servopin,HIGH);
delayMicroseconds(1500); // 1500 will set the servo to
digitalWrite(servopin,LOW); // mid position
delay(19); // gives time for the move can be unblocking code
This can be repeated to provide a continuous pulse. For situations where there is no or minimal load a servo may not move if the pulses stop. If you repeat the pulses with sithout the delay then some will be ignored. If say you are increasing the Microsecond delay to sweep the servo across and miss the delay after the pulse you will find it jumps serveral steps this applies if you use servoWrite without a pause too.
Once you do a detach the servo library function will not know which pin the servo is using.
-
attach()
does more than just initialize a variable: it starts a continuous stream of pulses at 50 Hz. Andwrite()
doesn't send a single pulse: it changes the width of all the subsequent pulses of the stream. These pulses are interrupt-driven, so you don't have to worry about program timing.Edgar Bonet– Edgar Bonet2024年10月13日 12:27:18 +00:00Commented Oct 13, 2024 at 12:27