PDA

View Full Version : Servo motor does not work correct



cesar35
- 15th June 2014, 20:24
Hello
Can someone help me.
I can not control a servo motor he is without direction.
here's codgo I'm using.
In the PC program I have a range between 700 a 2300.
Thank you.
RX VAR BYTE
POS VAR BYTE
X1 VAR BYTE

PROG:
serin2 RX_inp,16468,[wait("PC"),RX,POS]

IF RX = "A" THEN FRE
IF RX = "B" THEN TRA
IF RX = "C" THEN ESQ
IF RX = "D" THEN DIr
if RX = "E" THEN PAR
IF RX = "X" THEN SERV
GOTO PROG

FRE:
PORTB.0 = 0
PORTB.1 = 1
PORTB.2 = 1
PORTB.3 = 0
GOTO PROG
TRA:
PORTB.0 = 1
PORTB.1 = 0
PORTB.2 = 0
PORTB.3 = 1
GOTO PROG
ESQ:
PORTB.0 = 1
PORTB.1 = 0
PORTB.2 = 1
PORTB.3 = 0
GOTO PROG
DIR:
PORTB.0 = 0
PORTB.1 = 1
PORTB.2 = 0
PORTB.3 = 1
GOTO PROG

PAR:
PORTB.0 = 0
PORTB.1 = 0
PORTB.2 = 0
PORTB.3 = 0
GOTO PROG

SERV:
high SERVO1
pauseus X1*10:X1 = pos
low SERVO1
GOTO PROG

Demon
- 15th June 2014, 20:56
Did you make port B digital?

What PIC?

What CONFIG settings?

Do you want default oscillator settings?

What is RX_inp and SERVO1?

Do you want X1 to have initial value?

Robert

cesar35
- 15th June 2014, 21:05
Hello all well
I have a program on the PC that controls the motor ac
I trackbar that for servo motor with avariaves 700-2300
This half confused,

@ DEVICE PIC16F876A
@ DEVICE PIC16F876A,WDT_ON
@ DEVICE PIC16F876A,PWRT_ON
@ DEVICE PIC16F876A,PROTECT_off
@ DEVICE PIC16F876A,XT_OSC
define OCS 4
ADCON1 = 7
TRISC=%10000000:PORTC=%10000000
TRISA=%11111111:PORTA=%11111111
TRISB=%00000000:PORTB=%00000000
SYMBOL SERVO1=PORTB.0 'SERVO1
SYMBOL RX_INP=PORTC.7 'RF

HenrikOlsson
- 16th June 2014, 06:14
Hi,
A couple of issues of the bat:
If, by servo, you mean your typical RC servo it's not enough to send it one pulse. If you want it to move you need to send it pulses, usually at around 50Hz repetition rate, for at least as long as it tkaes for the servo to move to the new position but ideally you send it pulses all the time so that it can keep its position. As far as I can see you're only sending a single pulse - I don't think that's going to work.

You have POS declared as a BYTE but you're trying to store a value between 700 and 2300 - that's not going to work.

pauseus X1*10:X1 = pos
A typical RC servo want pulses with a width of 1-2ms. If you assign 2000 to POS (after changing it to a WORD) you're going to get a pulsewidth of 20000us or 20ms - I don't think that's going to work.

If you change POS to a WORD check the documentation of SERIN to see if it can handle WORD variables directly or if you need to give it the high and low byte separately. And, finally, I'm not sure what the purpose of copying POX to X1 but if there's a specific reason for it make sure you change X1 to WORD as well.

/Henrik.

cesar35
- 16th June 2014, 12:06
Thanks for the reply
I made you the servant said he moved to the left and and stop.
I cho I'm really confused.
Could you tell me what is wrong in this program
@ DEVICE PIC16F876A
@ DEVICE PIC16F876A,WDT_ON
@ DEVICE PIC16F876A,PWRT_ON
@ DEVICE PIC16F876A,PROTECT_off
@ DEVICE PIC16F876A,XT_OSC
define OCS 4
ADCON1 = 7
TRISC=%10000000:PORTC=%10000000
TRISA=%11111111:PORTA=%11111111
TRISB=%00000000:PORTB=%00000000

SYMBOL SERVO1=PORTC.0 'SERVO1
SYMBOL RX_INP=PORTC.7 'RF

RX VAR BYTE
POS VAR word
X1 VAR word

PROG:
serin2 RX_inp,16468,[wait("PC"),RX,POS]

IF RX = "A" THEN FRE
IF RX = "B" THEN TRA
IF RX = "C" THEN ESQ
IF RX = "D" THEN DIr
if RX = "E" THEN PAR
IF RX = "X" THEN SERV
GOTO PROG

FRE:
PORTB.0 = 0
PORTB.1 = 1
PORTB.2 = 1
PORTB.3 = 0
GOTO PROG
TRA:
PORTB.0 = 1
PORTB.1 = 0
PORTB.2 = 0
PORTB.3 = 1
GOTO PROG
ESQ:
PORTB.0 = 1
PORTB.1 = 0
PORTB.2 = 1
PORTB.3 = 0
GOTO PROG
DIR:
PORTB.0 = 0
PORTB.1 = 1
PORTB.2 = 0
PORTB.3 = 1
GOTO PROG

PAR:
PORTB.0 = 0
PORTB.1 = 0
PORTB.2 = 0
PORTB.3 = 0
GOTO PROG

SERV:
high SERVO1
pauseus X1*10:X1 = pos
low SERVO1
GOTO PROG

HenrikOlsson
- 16th June 2014, 12:39
Hi,

Could you tell me what is wrong in this program
I thought I did bring up least a couple of things that might be wrong.
You've corrected the variable size, that's good.

But,
* You are still doing the times 10 thing in the SERV subroutine, if the PC sends 700 you'll get a 7ms delay, what's the reason for it?
* You are still only sending a single pulse to the servo
* I took a brief look at the manual and as far as I can see SERIN2 can not directly handle WORDs, you need to split it, SERIN2 RX_inp,16468,[wait("PC"),RX,POS.HighByte, POS.LowByte] watch out for big vs little endian. Which brings me to the last thing...
* How is the PC sending the data? If it's sending it as ASCII, ie "1","2","3","4" instead of two bytes 4,210 then you need to use the DEC modifier in the SERIN2 statement.

/Henrik.

cesar35
- 16th June 2014, 18:12
Hello Henrik.
As you said I have to send high and low along with varaves between 700 and 2300.
did not know that controls a servo was a yes.
I am very grateful to you.

cesar35
- 16th June 2014, 23:37
Hello Henrik
And I do not know much about PicBasic Pro.
To do piquenos project I do.
I never did a project to control a servo motor by pc
You can explain me better.
I have change the vb.net program for this to work.
thank you

Demon
- 17th June 2014, 01:06
It would help to know the specs of the motor, just to be sure.

To some, a servo is used to unlock a car door, to others it can turn specific degrees.

The more information you provide, the more people can help.

(those 4 signals make me think of a bi-polar stepper motor)

Robert

EarlyBird2
- 17th June 2014, 05:54
You could also post the vb.net program.

cesar35
- 17th June 2014, 13:33
Hello thank you guys for the help.
Here is the data I'm sending to the pic
With vb.net
I control the camera using servo motor for movement

https://www.youtube.com/watch?v=vYvG5p3YPxQ&feature=youtu.be


Private Sub TrackBar1_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TrackBar1.Scroll
pos = CInt(TrackBar1.Value)
Label8.Text = pos
SerialPort1.Write("PC")
SerialPort1.Write("X")
SerialPort1.Write(pos)

'POS MAX 2300
'POS MIN 7000
End Sub

Demon
- 17th June 2014, 14:21
As far as I know, X1 will be 0 first time through, maybe. I always set variables to 0 at top of program.

PAUSEUS will be nothing so SERVO1 will be turned OFF quite fast.

Then the PIC will wait for the next SERIN from the PC, it won't emit more pulses until then.

Assuming your MODE is configured properly.

Robert

cesar35
- 17th June 2014, 15:48
Hello Robert okay
you have to make an example as I do
I think I'm losing myself in programming
Between two pic I did worked.
With pc always had the difficulty.
Thank you.

cesar35
- 17th June 2014, 17:11
:confused:

HenrikOlsson
- 17th June 2014, 18:55
My VB is severly rusted but I think you've got a format mismatch between what VB is sending and what the PIC is expecting - as I suggested in a previous post.
I think that SerialPort1.Write(pos) will send the content of variable pos as an ASCII string while the PIC is expecting two binary bytes, not an ASCII string.
If that's the case you need to change the VB program or the PIC program, on the PIC side you can use the DEC modifier to recieve an ASCII string consisting of decimal digits and parse that into a value.

Again, there's a big difference between sending a byte as binary, ie 123 and sending it as an ASCII string. If you loop the TX to RX on the PC and fire up a terminal program, what does the data look like?

/Henrik.

Demon
- 17th June 2014, 20:45
Hello Robert okay
you have to make an example as I do
I think I'm losing myself in programming
...

Sorry, have chores to do.

You really should start small and add one thing at a time. I suggest you practice SERIN first, then add the pulses to the servo.

Robert


Edit: check out the PBP sample programs, they cover a LOT of material.

EarlyBird2
- 18th June 2014, 07:40
Again, there's a big difference between sending a byte as binary, ie 123 and sending it as an ASCII string. If you loop the TX to RX on the PC and fire up a terminal program, what does the data look like?

/Henrik.

VB serialport.write defaults to ASCII characters so change PIC side and use DEC modifier.

EarlyBird2
- 20th June 2014, 06:37
Hello EarlyBird2
I modified the program (dec pos)
The servo move well.
have problem
I have no command (RX) not working AC motors
Could you tell me why (RX) does not work.
thank you

Could you explain more "I have no command (RX) not working AC motors. Could you tell me why (RX) does not work."

RX has the value "X" and the servo works so how is RX not working?

cesar35
- 20th June 2014, 10:28
Hello
After modifying (DEC POS) The RX does not work
I can send data to the rx ac motors not working.
So the servant move
I used (Servo gosub)
The servant problem has already works better
Thank you all.

serin2 RX_inp,16468,500,PAR,[wait("PC"),RX,DEC POS]

IF RX = "A" THEN FRE
IF RX = "B" THEN TRA
IF RX = "C" THEN ESQ
IF RX = "D" THEN DIr
GOSUB SERVO
GOTO PROG

SERVO:
servo1 = 1
PAUSEUS 1000 + pos
servo1 = 0
Pause 16
RETURN

EarlyBird2
- 20th June 2014, 10:54
You are saying that POS is received and works but "X" is not received.

Demon
- 20th June 2014, 12:48
I noticed he changed HIGH/LOW to 1/0.

Robert


Edit: (if I'm awake) a bipolar motor needs the 4 inputs to vary in a specific order (one for CW, one for CCW).

If you keep turning on the motor but these don't change state, I think you end up with the motor holding position.

cesar35
- 20th June 2014, 15:07
As I said the command RX does not work.
Here's a video made ​​in proteus.
https://www.youtube.com/watch?v=D8gVGu4qXmU&feature=youtu.be:mad:

EarlyBird2
- 20th June 2014, 22:21
The code you are running is not the code in #5 and #19.

Please post the code you are using.

EarlyBird2
- 20th June 2014, 22:51
As I said the command RX does not work.


RX is not a command. RX is a variable which is assigned an ASCII code when serin2 is executed.

I see you changed IF THEN to SELECT CASE. SELECT CASE is for values and not ASCII characters like "A".

Did it stop working when you made these changes?
Did you make these changes because it did not work with IF THEN?
Is the servo working if not has the servo ever worked?

cesar35
- 20th June 2014, 23:41
Hello all well
Here is the code


@ DEVICE PIC16F876A
@ DEVICE PIC16F876A,WDT_ON
@ DEVICE PIC16F876A,PWRT_ON
@ DEVICE PIC16F876A,PROTECT_off
@ DEVICE PIC16F876A,XT_OSC
define OCS 4
ADCON1 = 7
TRISC=%10000000:PORTC=%10000000
TRISA=%11111111:PORTA=%11111111
TRISB=%00000000:PORTB=%00000000

SYMBOL SERVO1=PORTB.0 'SERVO1
SYMBOL RX_INP=PORTC.7 'RF

RX VAR BYTE
POS VAR word

PROG:
serin2 RX_inp,84,500,MODATA,[wait("PC"),RX,DEC POS]

SELECT CASE RX
CASE "1"
GOSUB FRE
CASE "2"
GOSUB TRA
CASE "3"
GOSUB DIR
CASE "4"
GOSUB ESQ
CASE "5"
HIGH PORTB.0
pauseus 1000 + pos
LOW PORTB.0
Pause 16
END SELECT
GOTO PROG

FRE:
PORTC.0 = 0
PORTC.1 = 1
PORTC.2 = 1
PORTC.3 = 0
RETURN
TRA:
PORTC.0 = 1
PORTC.1 = 0
PORTC.2 = 0
PORTC.3 = 1
RETURN
ESQ:
PORTC.0 = 1
PORTC.1 = 0
PORTC.2 = 1
PORTC.3 = 0
RETURN
DIR:
PORTC.0 = 0
PORTC.1 = 1
PORTC.2 = 0
PORTC.3 = 1
RETURN

MODATA:

PORTB.0 = 0
PORTB.1 = 0
PORTB.2 = 0
PORTB.3 = 0
GOTO PROG

cesar35
- 21st June 2014, 01:48
Here the right code.
Please dis me if I'm on track.
sorry


@ DEVICE PIC16F876A
@ DEVICE PIC16F876A,WDT_ON
@ DEVICE PIC16F876A,PWRT_ON
@ DEVICE PIC16F876A,PROTECT_off
@ DEVICE PIC16F876A,XT_OSC
define OCS 4
ADCON1 = 7
TRISC=%10000000:PORTC=%10000000
TRISA=%11111111:PORTA=%11111111
TRISB=%00000000:PORTB=%00000000

SYMBOL SERVO1=PORTB.0 'SERVO1
SYMBOL RX_INP=PORTC.7 'RF

RX VAR BYTE
POS VAR word

PROG:
serin2 RX_inp,84,500,MODATA,[wait("PC"),RX,DEC POS]

SELECT CASE RX
CASE "1"
GOSUB FRE
CASE "2"
GOSUB TRA
CASE "3"
GOSUB DIR
CASE "4"
GOSUB ESQ
CASE "5"
HIGH PORTB.0
pauseus 1000 + pos
LOW PORTB.0
Pause 16
END SELECT
GOTO PROG

FRE:
PORTC.0 = 0
PORTC.1 = 1
PORTC.2 = 1
PORTC.3 = 0
RETURN
TRA:
PORTC.0 = 1
PORTC.1 = 0
PORTC.2 = 0
PORTC.3 = 1
RETURN
ESQ:
PORTC.0 = 1
PORTC.1 = 0
PORTC.2 = 1
PORTC.3 = 0
RETURN
DIR:
PORTC.0 = 0
PORTC.1 = 1
PORTC.2 = 0
PORTC.3 = 1
RETURN

MODATA:

PORTC.0 = 0
PORTC.1 = 0
PORTC.2 = 0
PORTC.3 = 0
GOTO PROG

EarlyBird2
- 21st June 2014, 06:00
RX is not a command. RX is a variable which is assigned an ASCII code when serin2 is executed.

I see you changed IF THEN to SELECT CASE. SELECT CASE is for values and not ASCII characters like "A".

Did it stop working when you made these changes?
Did you make these changes because it did not work with IF THEN?
Is the servo working if not has the servo ever worked?

Thanks for the code but you have not answered the questions.

EarlyBird2
- 21st June 2014, 06:19
Looking at the code "CASE "1" is saying CASE = "1" not CASE = 1 there is a big difference. "1" is a string with ASCII value of 49 and 1 is a value of 1.

CASE works with a value and not with strings but you can use the ASCII value.
So CASE "1" should be CASE 49
and CASE "A" should be CASE 65

for example.

cesar35
- 21st June 2014, 12:25
Looking at the code "CASE "1" is saying CASE = "1" not CASE = 1 there is a big difference. "1" is a string with ASCII value of 49 and 1 is a value of 1.

CASE works with a value and not with strings but you can use the ASCII value.
So CASE "1" should be CASE 49
and CASE "A" should be CASE 65

for example.

Hello
About your question
I modified the program to SELECT CASE.para get better to understand the program.

cesar35
- 21st June 2014, 12:33
Hello
Now already understand what you said.
on the servo seems to me that something is missing he is without direction
Here is the corrected code.
thank you

@ DEVICE PIC16F876A
@ DEVICE PIC16F876A,WDT_OFF
@ DEVICE PIC16F876A,PWRT_OFF
@ DEVICE PIC16F876A,PROTECT_OFF
@ DEVICE PIC16F876A,XT_OSC
define OCS 4
ADCON1 = 7
TRISC=%10000000:PORTC=%10000000
TRISA=%11111111:PORTA=%11111111
TRISB=%00000000:PORTB=%00000000

SYMBOL SERVO1=PORTB.0 'SERVO1
SYMBOL RX_INP=PORTC.7 'RF

RX VAR BYTE
POS VAR word
POS = 1500

PROG:
serin2 RX_inp,84,600,MODATA,[wait("PC"),RX,DEC POS]

SELECT CASE RX
CASE 65 'A
GOSUB FRE
CASE 66 'B
GOSUB TRA
CASE 67 'C
GOSUB DIR
CASE 68 'D
GOSUB ESQ
CASE 69 'E
HIGH PORTB.0
pauseus 1500 + pos
LOW PORTB.0
Pause 20
END SELECT
GOTO PROG

FRE:
PORTC.0 = 0
PORTC.1 = 1
PORTC.2 = 1
PORTC.3 = 0
RETURN
TRA:
PORTC.0 = 1
PORTC.1 = 0
PORTC.2 = 0
PORTC.3 = 1
RETURN
ESQ:
PORTC.0 = 1
PORTC.1 = 0
PORTC.2 = 1
PORTC.3 = 0
RETURN
DIR:
PORTC.0 = 0
PORTC.1 = 1
PORTC.2 = 0
PORTC.3 = 1
RETURN

MODATA:
PORTC.0 = 0
PORTC.1 = 0
PORTC.2 = 0
PORTC.3 = 0
GOTO PROG

Demon
- 22nd June 2014, 03:16
If the PC is not sending A, B, C and D in the proper sequence, the motor will not turn, MODATA will hold the motor in place.

Robert

HenrikOlsson
- 22nd June 2014, 09:18
Hi,


CASE works with a value and not with strings but you can use the ASCII value.
So CASE "1" should be CASE 49
and CASE "A" should be CASE 65

Both are equally fine.
CASE "A", CASE 65, CASE $41, CASE %01000001 all works and does the exact same thing.

/Henrik.

EarlyBird2
- 22nd June 2014, 09:24
Hi,


Both are equally fine.
CASE "A", CASE 65, CASE $41, CASE %01000001 all works and does the exact same thing.

/Henrik.

That is useful information.
The mystery deepens then because the way CASE was written was not the problem. But CASE "A" did not work but CASE 65 does. Or does it? Is the question now. I need more feedback!

HenrikOlsson
- 22nd June 2014, 10:57
Hi,

But CASE "A" did not work but CASE 65 does. Or does it?
I have no idea... All I can say is that CASE "A" works perfectly fine for me, I use it extensively in several applications, as an example, here's a snippet:

Select Case CmdBuffer[0] ' Decide what to do based on the first character in the buffer

CASE "A", "a" ' Set accleration feedforward
GOSUB ReadCmdBuffer
If ValueReceived then pid_Acc_kFF = RxValue
MenuLine = 6
PrintLine = 1

/Henrik.

cesar35
- 22nd June 2014, 13:43
Hello friends
Now I'm more confused
For example I do not understand anything too advanced for min
I do not know what else to mofificar my program
To control DC motors all works fine
I thank all of you for the tension
sorry for your time.
Thank you all for having me conpartilhado your knowledge at Pic basic pro
:D:D

EarlyBird2
- 22nd June 2014, 21:54
Hello friends
Now I'm more confused
For example I do not understand anything too advanced for min
I do not know what else to mofificar my program
To control DC motors all works fine
I thank all of you for the tension
sorry for your time.
Thank you all for having me conpartilhado your knowledge at Pic basic pro
:D:D

I am pleased it is working and no need to say sorry. I am here to help if I can.

Pimentel
- 23rd June 2014, 13:02
Colega, você é do Brasil? Pelo programa (frente/tras/dir/esq) e pelo seu nome achei que sim! Se for fica mais fácil da gente trocar idéias pq meu inglês tá mto ruim, kkk!
Manda um email privado confirmando que a gente troca uma idéia. Eu uso servo com sucesso e acho que posso te ajudar. Abraço
Pimentel

Demon
- 23rd June 2014, 14:12
Google translate:


Colleague, you are from Brazil? The program (front / rear / left / right) and his name thought so! If it is easier on us exchange ideas coz my english okay mto bad, kkk! Send a private email confirmation

Not perfect but close enough.

Robert
:)