Author Topic: Sequencing Servos and Autonomous Servo Control w/ Sharp IR  (Read 12777 times)

0 Members and 1 Guest are viewing this topic.

Offline CanabotsTopic starter

  • Contest Winner
  • Robot Overlord
  • ****
  • Posts: 245
  • Helpful? 6
  • It's not a bug, it's a feature!
    • Salmigondis Tech
Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« on: November 28, 2008, 09:03:50 PM »
Ok,

So I can now properly control servos and compute Sharp IR inputs via a microcontroller.

There are two separate questions in this post:

1. This is the code that I use to make my servo turn one way of another (depending on the program written)
Code: [Select]
#include <pic.h>

__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT \
  & UNPROTECT & BORDIS & IESODIS & FCMDIS);

int x, y;

delay(int xvalue,int yvalue)
{

for(x = 0; x < xvalue; x++);
for(y = 0; y < yvalue; y++);

return;
}

main()
{
PORTA  = 0;
CMCON0 = 7;
ANSEL  = 0;
TRISA4 = 0;


while(1 == 1) // Loop forever
{

RA4 = 1; // Pulse high
delay(2,200);
RA4 = 0; // Low
delay(19,243); // 18 ms
}
}

Does anyone have any ideas how I can sequence servo movements using this code for the actual servo movements? I've tried a few Ideas to no avail.



2. This is code I'v tried to make my servo turn one way or another depending on whether or not an object's been detected:
Code: [Select]
#include <pic.h>

__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT \
  & UNPROTECT & BORDIS & IESODIS & FCMDIS);

int x, y;

delay(int xvalue,int yvalue)
{

for(x = 0; x < xvalue; x++);
for(y = 0; y < yvalue; y++);

return;
}

 
main()
{
PORTA  = 0;
CMCON0 = 7;
ANSEL  = 0;
TRISA4 = 0;
TRISA3 = 1;

while (1)
{
if (RA3 == 1)
{
          RA4 = 1; // Pulse high
          delay(2,200);
          RA4 = 0; // Low
          delay(19,243); // 18 ms }
else
{

                RA4 = 1; // Pulse high
          delay(1,500);
          RA4 = 0; // Low
          delay(19,243); // 18 ms
}
}
}

For some reason it's not working. Is there some line that I may be missing? Yes, I've also done some searches on the internet.

I am using MPLAB IDE and PIC C Lite compiler along with a PIC16F684 microcontroller.


Sorry for the big post :(.

Your input is much appreciated (as I always say :))

Canabots



« Last Edit: November 29, 2008, 08:44:41 PM by Canabots »
My robotics, electronics, software, or other stuff blog:
www.saltech.wordpress.com

Offline CanabotsTopic starter

  • Contest Winner
  • Robot Overlord
  • ****
  • Posts: 245
  • Helpful? 6
  • It's not a bug, it's a feature!
    • Salmigondis Tech
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #1 on: November 30, 2008, 01:12:51 PM »
Uh oh... there's now another issue...

Using this code:
Code: [Select]

while (1 == 1)
{
RA4 = 1; // Pulse high
delay(2,200);
RA4 = 0; // Low
delay(19,243); // 18 ms
                }

I could change the position of the servo by just changing the first delay.

That no longer seems to be the case... The servo only turns all the way to the right (actually, both my servos only do that).

Does anyone have any ideas of what this means? Do you think it's a microcontroller problem or a programming problem?
« Last Edit: November 30, 2008, 01:40:31 PM by Canabots »
My robotics, electronics, software, or other stuff blog:
www.saltech.wordpress.com

Offline pomprocker

  • Supreme Robot
  • *****
  • Posts: 1,431
  • Helpful? 16
  • Sorry miss, I was giving myself an oil-job.
    • Nerdcore - Programming, Electronics, Mechanics
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #2 on: November 30, 2008, 01:57:59 PM »
you can to create a pulse width.


set pin low for 20ms
bring pin high for anywhere between 1ms and 2ms (1.5ms being center)
repeat

Offline CanabotsTopic starter

  • Contest Winner
  • Robot Overlord
  • ****
  • Posts: 245
  • Helpful? 6
  • It's not a bug, it's a feature!
    • Salmigondis Tech
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #3 on: November 30, 2008, 02:50:49 PM »
I would use pwm, but the problem is, I have never seen any good examples of it for the PIC mcu. I do own 123 Microcontroller experiments for the evil genius, but the pwm example is not straightforward as it tries to involve other things to the program.

I would prefer using your preposed method
set pin low for 20ms
bring pin high for anywhere between 1ms and 2ms (1.5ms being center)
repeat

but I have not been able to find any ressources on the internet explaining the concept and how to make that simple program. If someone can teach me how to do this or to implement it, then I would really appreciate it. :)
« Last Edit: December 01, 2008, 03:33:01 PM by Canabots »
My robotics, electronics, software, or other stuff blog:
www.saltech.wordpress.com

Offline CanabotsTopic starter

  • Contest Winner
  • Robot Overlord
  • ****
  • Posts: 245
  • Helpful? 6
  • It's not a bug, it's a feature!
    • Salmigondis Tech
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #4 on: December 01, 2008, 03:44:29 PM »
Also, If anyone knows any good links or can atleast point me in the right direction, that would also be great.

Thank you in advance for all your troubles!

Canabots
My robotics, electronics, software, or other stuff blog:
www.saltech.wordpress.com

Offline Ro-Bot-X

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,431
  • Helpful? 25
  • Store: RoBotXDesigns.ca
    • Ro-Bot-X Designs
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #5 on: December 01, 2008, 08:58:09 PM »
What does delay(2,200) means? And delay(19,243)?

For AVRs you have to set the fuses to use a certain clock speed and then to tell the compiler what clock speed you are using. If the compiler uses a different clock speed you get weird results. Does the same apply to PICs?
Check out the uBotino robot controller!

Offline AdvsNoob

  • Robot Overlord
  • ****
  • Posts: 156
  • Helpful? 0
  • Younge Inventer
    • Uni Coding
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #6 on: December 01, 2008, 09:43:37 PM »
i found this on the Arduino website...

Code: [Select]
// Sweep
// by BARRAGAN <http://barraganstudio.com>

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int pos = 0;    // variable to store the servo position

void setup()
{
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop()
{
  for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
  {                               
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

That is for the servo.

I am new with the arduino so im not sure if it will work with the PIC16F684 microcontroller.

Offline cosminprund

  • Robot Overlord
  • ****
  • Posts: 284
  • Helpful? 8
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #7 on: December 02, 2008, 01:07:06 AM »
Code: [Select]
[quote author=Canabots link=topic=5967.msg45559#msg45559 date=1228072371]
while (1 == 1)
{
RA4 = 1; // Pulse high
delay(2,200);
RA4 = 0; // Low
delay(19,243); // 18 ms
                }
[/quote]

I'm also using the PIC16F684 but I'm doing my programming with assembler. What oscillator mode are you using? I'm having an hard time understanding your __CONFIG macro. If you're using the internal oscillator mode please remamber it's not a very good timing source. I also assume the "delay" statement takes it's parameter in uC CYCLES, not milliseconds. Just re-experiment with the values. Here's what I've done:

Make a simple program that moves the servo to a fixed position. Start with a random delay (ex: delay(1500).). Is it centered or is it off-center? Change the value and see where the servo goes (this might require re-programming the PIC). Move it towards the left/right until you hear an humming sound, then back off a little. Do this for both directions, you'll get some numbers for what timing you need to get the servo all the way to the left and all the way to the right, without getting the humming sound.

My values are those:
delay(800) moves the servo all the way to the left.
delay(1500) moves the servo all the way to the right.

I also had different values initially. I guess I simply deleted my OSCAL calibration value when I've issued an "erase" command to my programmer :) Oh well, I'll be moving to an external crystal oscillator any way, as soon as I figure out what capacitors I need for my 4MHz crystal.

Good luck,
Cosmin Prund (my first post :) )


Offline CanabotsTopic starter

  • Contest Winner
  • Robot Overlord
  • ****
  • Posts: 245
  • Helpful? 6
  • It's not a bug, it's a feature!
    • Salmigondis Tech
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #8 on: December 02, 2008, 05:10:34 PM »
WOW!! Thank you for all those responses!


To Ro-Bot-X: The  "delay(value)" was for the timing of the pulses. And as far as I know, you don't have to set the same fuses or clock speeds as the compiler (well, I haven't up to date, and all my other MCU projects worked fine).

To AdvsNoob: I don't know if the Arduino code is compatible with PICs, but if I can't get a solution within the next week or so, I will probably try it out. Thank you.

To cosminprund: HURRAH!! It's good to see someone else using the same microcontroller as me :). Here's a litteral translation of my _CONFIG macro (same order as appears in code) :

_CONFIG( Internal Oscillator, RA4 IO Pin  &  Disable Watchdog Timer  &  70ms Power-Up delay  &     MCLR Pin Function Inactive   &   Program memory Protection   &   Brownout Detect   &   Switchover Mode Disabled   &   Fail-Safe Clock Disabled)


The "delay" statement is in MCU cycles, if I'm not mistaken. Well, I got the general sense of the code from here: http://www.electro-tech-online.com/micro-controllers/35216-servo-controller-using-pic16f877a.html

Is it bad if the servo hums? It does that while using my current code. Also, I think the oscillator is at a default 8Mhz for my program. I'm about to try your values. I'll let you know if it works.

Thank you So Much For all these posts and help everybody! ;D It is all VERY appreciated! :D

Canabots
« Last Edit: December 02, 2008, 05:11:30 PM by Canabots »
My robotics, electronics, software, or other stuff blog:
www.saltech.wordpress.com

Offline CanabotsTopic starter

  • Contest Winner
  • Robot Overlord
  • ****
  • Posts: 245
  • Helpful? 6
  • It's not a bug, it's a feature!
    • Salmigondis Tech
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #9 on: December 02, 2008, 07:40:46 PM »
cosminprund, is your microcontroller clocked at 4Mhz for this program? Also, what was the value for  "delay" during the 10-20ms part? I reprogrammed the MCU using your values, but I got the same results.

Canabots
« Last Edit: December 02, 2008, 08:05:45 PM by Canabots »
My robotics, electronics, software, or other stuff blog:
www.saltech.wordpress.com

Offline cosminprund

  • Robot Overlord
  • ****
  • Posts: 284
  • Helpful? 8
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #10 on: December 03, 2008, 02:13:41 AM »
Theorethically my MCU is clocked at 8Mhz. Practically it's a wired value, 6Mhz I think. I allready said I think I messed up it's OSCAL (oscilator calibration value) and I'm not planing to fix it, I'll be switching to external quartz oscilator over the weekend. Here's how I came up with the 6Mhz value: I made a delay procedure that was supposed to take up exactly 1 minute, and I made an LED blink before and after the delay. I clocked this using an digital clock and noticed it takes much longer then 60 seconds.

Abount the humming noise: I'm experimenting to find the propper delay times for the servo and there's a very good chance I'll be going over it's left or right limit. When the servo is at it's limit it will be mechanically stopped by it's internal limiting tabs and that puts strain on everything (motor, gears, battery). I'll decrease the delay until I hear that sound (that's the "humming" noise I was talking about). When I hear the noise I know I found the servo's limit. Next I'll increase the delay until it the humming noise stops! That's the lower delay limit I'll be using. Next I'll do the same thing for the other limit. I'd like to say "left" and "right" here but I've got 2 different kinds of servos on my hand and they don't move in the same direction when the delay gets short. One moves to the left, the other moves to the right.

As for the pause betwen the pulses, I also find that experimentally. I'd like to use some proper milisecond delays here so the timing would be portable from one MCU to the next but since my MCU has an wired internal oscilator I can't do that (yet).

Offline CanabotsTopic starter

  • Contest Winner
  • Robot Overlord
  • ****
  • Posts: 245
  • Helpful? 6
  • It's not a bug, it's a feature!
    • Salmigondis Tech
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #11 on: December 03, 2008, 06:53:20 AM »
Once again, thank you very much, that does clear up a few problems in my head.

Also, I found this line of code on the internet (unfortunately, I don't remember the site):

#use DELAY(clock=8000000) // 8MHz clock

It is supposed to tell the compiler the speed of the clock in the program and then all you would have to do is enter in "delay_us(value)" or "delay_ms(value)" for uS and mS delays. But when I compile, the build window shows a single error:

2.4 illegal # directive "use"

Does anyone know how this can be fixed or have an alternative to that line?

Canabots

EDIT: 2.4 is the line/column number
« Last Edit: December 03, 2008, 07:26:32 AM by Canabots »
My robotics, electronics, software, or other stuff blog:
www.saltech.wordpress.com

Offline cosminprund

  • Robot Overlord
  • ****
  • Posts: 284
  • Helpful? 8
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #12 on: December 03, 2008, 07:34:59 AM »
I can't help you with that, I'm programming my PIC with assembler. An tip those: Make sure the code you found was for your version of the "C" compiler! My guess would be that it's not for your compiler.

Offline Rebelgium

  • Supreme Robot
  • *****
  • Posts: 637
  • Helpful? 0
  • It's called the future ... We like it here
    • orgcrime.net
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #13 on: December 03, 2008, 01:22:22 PM »
I can't help you with that, I'm programming my PIC with assembler. An tip those: Make sure the code you found was for your version of the "C" compiler! My guess would be that it's not for your compiler.

just an FYI,
programming in assembler is going to progress very slow.
Assembler is the most powerfull code possible, ever. But it's very hard to code complicated programs, therefor taking much more time.
I strongly recommend using C.
Very powerfull (second most powerfull of all languages), and alot faster and easier than asm.
To relax after some hard work on robotics: A very fun free online text based MMORPG
orgcrime.net

Offline CanabotsTopic starter

  • Contest Winner
  • Robot Overlord
  • ****
  • Posts: 245
  • Helpful? 6
  • It's not a bug, it's a feature!
    • Salmigondis Tech
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #14 on: December 03, 2008, 05:00:34 PM »
I find assembler REALLY confusion. So I put that aside for another time :D

Anyhoo, turns out the compiler for that line of code was really CCS, not PICC Lite! Oh well. I'll figure it out.

Does anyone know other ways of creating delays? I heard there was a sleep function that could suspend and action timed in milliseconds. Any clues?

Thank you!

Canabots
« Last Edit: December 03, 2008, 05:02:24 PM by Canabots »
My robotics, electronics, software, or other stuff blog:
www.saltech.wordpress.com

Offline cosminprund

  • Robot Overlord
  • ****
  • Posts: 284
  • Helpful? 8
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #15 on: December 04, 2008, 12:41:29 AM »
just an FYI,
programming in assembler is going to progress very slow.
Assembler is the most powerfull code possible, ever. But it's very hard to code complicated programs, therefor taking much more time.
I strongly recommend using C.
Very powerfull (second most powerfull of all languages), and allot faster and easier than asm.

My day-job is programming, my "robotics" and mcu programming is working to become my hobby. I can't program in any high-level language before I understand what the CPU can do because the high level language will only hide the CPU's inefficiency. This is especially true for microcontrollers as they have lots of limitations (limited hardware stack, low instruction count making certain constructs difficult, tiny amounts of memory, the list goes on).

Offline cosminprund

  • Robot Overlord
  • ****
  • Posts: 284
  • Helpful? 8
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #16 on: December 04, 2008, 01:14:19 AM »
Does anyone know other ways of creating delays? I heard there was a sleep function that could suspend and action timed in milliseconds. Any clues?

Here's an clue. You set up an timer that will trigger an interrupt. You put your MCU to sleep. When the counter goes to zero your MCU will wake up. The catch here is that the MCU has no idea what a millisecond is, you need a way to transform that millisecond into clock cycles and configure the counter/timer in number of clocks, not in milliseconds - once you've done that you'll realise it's much easier to control an servo without going to sleep.

Also you need finer precision for controlling an servo, giving the delays in milliseconds would give you only 2 possible positions: all the way to the left and all the way to the right, with nothing in betwen. You'd need to give the delay in something that's smaller and it's an multiple of the time it takes to run one single instruction on your MCU. That's around 200 nanoseconds if your MCU runs at 8MHz. Depending on what you want to do with your servo an number of fixed positions might be enough. Ex: straight froward, slightly to the left, all the way to the left, slightly to the right, all the way to the right. If that's enough you may be able to simply hard-code the delays in CPU cycles and be done with it!

Offline CanabotsTopic starter

  • Contest Winner
  • Robot Overlord
  • ****
  • Posts: 245
  • Helpful? 6
  • It's not a bug, it's a feature!
    • Salmigondis Tech
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #17 on: December 04, 2008, 09:18:51 PM »
Oh! By "sleep", I didn't mean the microcontroller shuts down (if that's how you interpretted it, I should have explained it better. Sorry!). The Microcontroller would stay awake, it would just let the instruction pause for whatever amount of milliseconds.


Also, that was a beautiful explanation. The only problem is that I'm too noob to be able to figure out how to program that :-[, but I REALLY DO appreciate all your help :). I have looked into file linking, and how many people use that for their projects so they only have  to state something in the program, and it will be interpreted and execute (I'm likely mistaken, so correct me f I'm wrong). Does anyone have experience with this?

Thank you!
Canabots
My robotics, electronics, software, or other stuff blog:
www.saltech.wordpress.com

Offline cosminprund

  • Robot Overlord
  • ****
  • Posts: 284
  • Helpful? 8
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #18 on: December 05, 2008, 01:43:27 AM »
Oh! By "sleep", I didn't mean the microcontroller shuts down (if that's how you interpretted it, I should have explained it better. Sorry!). The Microcontroller would stay awake, it would just let the instruction pause for whatever amount of milliseconds.

The microcontroller has an SLEEP instruction that puts the MCU to sleep (it will do *nothing* until something wakes it up). Technically it's not "shut down" but it's very close to that (I think Microchip calls that state "NanoWatt" because it uses very little power). To confuse you further I've noticed a similar FUNCTION used with the "C" or "PICBASIC" language that takes one parameter and works similar to what you call delay.


Quote
I have looked into file linking, and how many people use that for their projects so they only have  to state something in the program, and it will be interpreted and execute (I'm likely mistaken, so correct me f I'm wrong). Does anyone have experience with this?

Give me an description of what you're tyring to do and I'll make an example for you in whatever language you're using. If possible include a picture of your PIC on it's development board / breadboard / whatever you're using. The description should include exactly where you're connecting your servo (what PIN). If you've got LEDS connected, please let me know where you've got them connected.

Fill in the following:

I'm using this compiler ...........
My servos signal pin is connected to this microcontroller pin ............. (pin number, pin name, both is better)
I've got an LED connected to this microcontroller pin ............ (pin number, pin name, both is better); Where's the other LED pin connected? To the GND or to "+"?
I would like to see the servo do this ............................. (ex: move from left to right and back like the windshield wiper of a car does)

Offline CanabotsTopic starter

  • Contest Winner
  • Robot Overlord
  • ****
  • Posts: 245
  • Helpful? 6
  • It's not a bug, it's a feature!
    • Salmigondis Tech
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #19 on: December 05, 2008, 06:26:30 AM »
To confuse you further I've noticed a similar FUNCTION used with the "C" or "PICBASIC" language that takes one parameter and works similar to what you call delay.

The latter is what I was the function I was thinking about, thanks.


I'm using this compiler  PICC Lite
My servos signal pin is connected to this microcontroller pin #11, RA2
I've got an LED connected to this microcontroller pin (No LEDs)
I would like to see the servo do this move from left to right and back like the windshield wiper of a car does

Current code on PIC16F684:
Code: [Select]
include <pic.h>

__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT
 & BORDIS & IESODIS & FCMDIS);

int x, y;

delay(int xvalue,int yvalue)
{

for(x = 0; x < xvalue; x++);
for(y = 0; y < yvalue; y++);

return;
}

main()
{
PORTA  = 0;
CMCON0 = 7;
ANSEL  = 0;
TRISA2 = 0;

while(1 == 1) // Loop forever
{

RA2 = 1; // Pulse high
delay(0,300);
RA2 = 0; // Low Pulse
delay(12,222);
}
}

Thank you so much for all your troubles cosmindprund. :)

Canabots


PS: Picture is coming, I just have to shrink the size.
« Last Edit: December 05, 2008, 06:51:21 AM by Canabots »
My robotics, electronics, software, or other stuff blog:
www.saltech.wordpress.com

Offline cosminprund

  • Robot Overlord
  • ****
  • Posts: 284
  • Helpful? 8
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #20 on: December 05, 2008, 08:03:30 AM »
I'll get back with the code as soon as I get home (I'm at work now). I think there's a bit of time-zone difference between us, you might only see the answer on your tomorrow :)
You might want to connect an LED somewhere, you need some form of output to test with. What if your PIC is deffective? What if your programmer is deffective?

Offline CanabotsTopic starter

  • Contest Winner
  • Robot Overlord
  • ****
  • Posts: 245
  • Helpful? 6
  • It's not a bug, it's a feature!
    • Salmigondis Tech
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #21 on: December 05, 2008, 06:13:00 PM »
Hmmmmmmm...

Nope, no defective programmer/controller. ;D That's a great advantage in the PICkit 1. Comes with built in LEDs and push button switch, so I can make sure it works without have to take it out of the Microcontroller.

Quote
I'll get back with the code as soon as I get home (I'm at work now). I think there's a bit of time-zone difference between us, you might only see the answer on your tomorrow

No need stress yourself! You're doing a HUGE favour to me and I'm very grateful for it! You don't have to rush :).

SOOOOOO Many thanks! :D

Canabots
« Last Edit: December 05, 2008, 06:13:52 PM by Canabots »
My robotics, electronics, software, or other stuff blog:
www.saltech.wordpress.com

Offline cosminprund

  • Robot Overlord
  • ****
  • Posts: 284
  • Helpful? 8
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #22 on: December 06, 2008, 02:31:29 AM »
I've also got the PICKit1, it's an nice kit but there's only so much you can do with it while keeping the MCU in the "Evaluation" socket - so I also got an ICD2 to help me with programming in the target circuit. It makes a lot of difference! I can make a round-trip reprogramming (change some delay, rebuild, program, test) in 10 seconds!

About the problem I'm working on (making the servo do something usefull). I'll need to do some more testing tonight. Last night I've got the PICC Lite compiler working and in my opinion I managed to get the timings right. Unfortunately I made my circuit use a 9V battery. After it quiclky consumed two batteries I connected my circuit to a 15V battery from my battery-operated drill. Unfortunately the huge voltage and the high power consumption of the servo would make my 7805 to hit to 100 deg Celsiius (212 degrees Fahrenheit) in about 15 seconds - that's not enough time to make any tests. I've left an RC 7V battery pack in the charger so tonight I should have propper power to continue my tests.

Anyway, no that I've played with PICC Lite I've spoted two problems with the code you posted. I'm talking about this function:
Quote
delay(int xvalue,int yvalue)
{
  for(x = 0; x < xvalue; x++);
  for(y = 0; y < yvalue; y++);
  return;   
}

Problem 1: Your function is made up of two for loops. You've got an terminator (";") after the first for. That tels the compiler the first for is done, and it's actually an empty loop. It will loop "xvalue" times and then move to the next for loop and loop an other "yvalue" times in there. Because of the ";" the compiler treats the two for statements sequentially! You most likely wanted the second for (the one counting to "yvalue") to be run "xvalue" times. To acheave that you simply remove the ";" after the first for! Here's why. The sintax for the "for" statement sayis it looks like this:

for (init;cond;inc) instruction;

"init" is the statement you use to initialise the loop (ie: "x=0");
"cond" is the condition evaluated to know if the lopp is to be terminated ("x<xvalue");
"inc" is the statement used to increment the loop variable ("x=x+1");
"instruction" tels the compiler what to do every loop. In the "C" language you can have an empty instruction. Because the first "for" statement is followed by an ";" the "C" compiler thinks it's a for statement with no "instruction" - perfectly valid! By removing the ";" from the first for you're actually telling the "C" compiler to run the first for statement and, on every loop, run the second for statement - the second for statement takes the place of "instruction" in the sample above.

Problem 2: Your "delay" function is using variables declared as "Int". The HI-TECH PICC compiler considers an "Int" to be an 16 bit variable, no matter what the MCU is! The PIC16F684 is an 8bit processor, and that means the 16 bit variable is actually made up of two memory locations/variables (or "file registers" as the MCU calls them). This might not be a problem in usual functions but it is a problem in a "delay" function because you want the delay to be highly predictable. Becuase you're using an 16 bit variable the HI-TECH PICC compiler generates smart code that detects the use of the high-byte and this means you'll allways get a penalty (something like 4 instruction cycles) and it also makes the timing non-linear. Example: If you call delay(255) the high byte would be zero and the code would smartly skip part of the loop. If you call delay(256) the high byte would no longer be zero and the code would take a different route, making the time difference betwen delay(255) and delay(256) non linear! To make this long story short you'll need to change the "Int" types into "unsigned char" :)

Some other things I've measured. The MCU is running at 4Mhz with the __CONFIG you showed me. I don't think the internal oscilator supports 8Mhz.

I also found some nice "delay" routines on the Microchip site. Look here:
http://www.microchipc.com/sourcecode/#delay16x
You want the files at "Delay and Timeout Routines for Hi-Tech C (PIC16Fx core)"
To use those files you'll need to download the archive and extract the files "delay.c", "delay.h" and "always.h" into your projects' directory. Add the file "delay.c" to your project (in MPLAB). Add a line like this to your main.c file:
Quote
#include "delay.h"
Open up the "delay.h" file and edit the first line, that's where the MCU clock speed is set up. Change that to read "4Mhz" (don't tuch the zeroes, change the "16" with "4").


After you do that you can use the following routines in your main function for delays:

This gives a 1 second delay. I've tested this with an LED (on for 1 second, off for 1 second) + an stopwatch and it's accurate - this means the delay routines are OK.
Quote
  DelayMs(250);
  DelayMs(250);
  DelayMs(250);
  DelayMs(250);
DelayMs takes un "unsigned char" - that's an number from 0 to 255. To get a 1 second delay we'd need 1000 milliseconds. Since we can't call DelayMs(1000) we're calling the function 4 times with 250 milliseconds - that gives 1 second.

This gives a 1,5 millisecond delay. Technically this would be the delay to move the servo to it's middle position:
Quote
  DelayMs(1);
  DelayUs(250);
  DelayUs(250);

DelayUs takes an "unsigned char" - again, that's an number from 0 to 255 and generates a delay of the given ammount in picoseconds. One millisecond is made up 1000 picoseconds. 1 millisecond + 500 picoseconds gives 1,5 milliseconds!

According to http://www.societyofrobots.com/actuators_servos.shtml we need to send the servo the high pulse "a few dozen times a second". Let's take that to be 2 dozens, that's 24 times a second. This requires a pause betwen pulses of about 41 milliseconds. This code should do that:
Quote
  DelayMs(41);

Putting it all toghether the code to move the servo to it's middle position should look something like this. Please note the code did not work for me - but I assume that's because of my power problems. I will test it tonight with the good battery:
Quote
#include <pic.h>
#include "delay.h"

__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT
 & BORDIS & IESODIS & FCMDIS);

main()
{
  TRISA = 0b11111011; // You need to make the TIRS bit "0" to make the bit an output; Using a binary constant is easy to read

  while(1 == 1)
  {
    RA2=1; // Make the bit high
    DelayMs(1);
    DelayUs(250);
    DelayUs(250);
    RA2=0; // The bit goes low
    DelayMs(41);
  }
}

Offline CanabotsTopic starter

  • Contest Winner
  • Robot Overlord
  • ****
  • Posts: 245
  • Helpful? 6
  • It's not a bug, it's a feature!
    • Salmigondis Tech
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #23 on: December 06, 2008, 07:15:34 AM »
For some reason, the "DelayMs" and "DelayUs" are undefined symbols according to the build window.
Do I have to make them into unsigned char's?

I am using the same code that you showed in the end of your post.


Thank you!!! ;D

Canabots
« Last Edit: December 06, 2008, 07:24:23 AM by Canabots »
My robotics, electronics, software, or other stuff blog:
www.saltech.wordpress.com

Offline cosminprund

  • Robot Overlord
  • ****
  • Posts: 284
  • Helpful? 8
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #24 on: December 06, 2008, 08:04:50 AM »
I typed the code in the forum window, take a look in "delay.h" near the bottom, see exactly what the name is. "C" is case-sensitive.

Offline CanabotsTopic starter

  • Contest Winner
  • Robot Overlord
  • ****
  • Posts: 245
  • Helpful? 6
  • It's not a bug, it's a feature!
    • Salmigondis Tech
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #25 on: December 06, 2008, 08:10:00 AM »
THE CODE WORKS!!!!!!!!!! :D

I forgot to add one of the header files (oops).

Anyway, the servo is generally centered, probably a few degrees off (but that's ok ;D)

Thank you Soooooooo much for all that help cosminprund :) I learned alot. Same for the rest of the people who took part in this topic.

Now, It's time to make that servo go in sequenced movements and autonomous control

Thanks!
Canabots
My robotics, electronics, software, or other stuff blog:
www.saltech.wordpress.com

Offline CanabotsTopic starter

  • Contest Winner
  • Robot Overlord
  • ****
  • Posts: 245
  • Helpful? 6
  • It's not a bug, it's a feature!
    • Salmigondis Tech
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #26 on: December 06, 2008, 10:59:35 AM »
Autonomous IR servo control works!!!!!

But I don't understand how to loop the servo pulse cycles and make them go in sequenced movements. I've tried a few things (none of them worked :( ). Any ideas?

Canabots
My robotics, electronics, software, or other stuff blog:
www.saltech.wordpress.com

Offline Admin

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,703
  • Helpful? 173
    • Society of Robots
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #27 on: December 10, 2008, 03:09:24 AM »
Quote
But I don't understand how to loop the servo pulse cycles and make them go in sequenced movements.
Do you mean like a pre-recorded sequence of motions to use later?

Offline CanabotsTopic starter

  • Contest Winner
  • Robot Overlord
  • ****
  • Posts: 245
  • Helpful? 6
  • It's not a bug, it's a feature!
    • Salmigondis Tech
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #28 on: December 10, 2008, 05:21:49 PM »
Hmmm...

No, I was thinking more along the lines of following this code:
Code: [Select]
#include <pic.h>
#include "delay.h"

__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT
 & BORDIS & IESODIS & FCMDIS);

main()
{
  TRISA = 0b11111011; // You need to make the TIRS bit "0" to make the bit an output; Using a binary constant is easy to read

  while(1 == 1)
  {
    RA2=1; // Make the bit high
    DelayMs(1);
    DelayUs(250);
    DelayUs(250);
    RA2=0; // The bit goes low
    DelayMs(18);
  }
}

but by looping it for a defined period of time, then by moving on to another set of pulses for a defined period of time, and allowing it to cycle though that sequence forever.

Thanks! :)
« Last Edit: December 10, 2008, 05:23:13 PM by Canabots »
My robotics, electronics, software, or other stuff blog:
www.saltech.wordpress.com

Offline cosminprund

  • Robot Overlord
  • ****
  • Posts: 284
  • Helpful? 8
Re: Sequencing Servos and Autonomous Servo Control w/ Sharp IR
« Reply #29 on: December 11, 2008, 01:55:23 AM »
I don't understand the requirements. Can you post an better example? Anyway, here's a modified bit of code that should work for two servos, one connected to RA2 and one connected to RA1. Please note I wrote the code in the forum window, there might be small syntax errors but the general idea should be ok.

What the code does. Imagine the two windshield wipers on a car. Imagine you've got two servos, one for each windshield wiper. The first sequence will make the two wipers move from left to right and back, at the same time. It will take 10 seconds to move from left to right and another 10 seconds to move from right to left. When that's done the two servos will start moving in the opposite directions (one "wiper" moves from left to right, the other "wiper" moves from right to left). This will happen 4 times faster then the first example!

Code: [Select]
#include <pic.h>
#include "delay.h"

__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT
 & BORDIS & IESODIS & FCMDIS);

// This routine takes two parameters, from 0 to 250, that will represent 250 possible positions
// for every one of the two servos.
void servopulse(unsigned char PulseRA2, unsigned char PulseRA1) {
  // First pulse RA2
  RA2=1;
  DelayMs(1);
  Delay(PulseRA2);
  Delay(PulseRA2);
  RA2=0;
  // Now pulse RA1
  RA1=1;
  DelayMs(1);
  Delay(PulseRA1);
  Delay(PulseRA1);
  RA1=0;
  // Wait for a while; The delay is shorter then the
  // original delay to account both 2ms pulses
  DelayMs(16); 
}

// This is one possible first sequence for the servos. Both servos will move at the same time
// to the same positions. I want the full swing from left to right to take about 10 seconds; Since I'll
// have 250 steps for each servo, the servo will need to hold each of those 250 steps for
// (20 * 1000) / 250 = 40 ms. Since the "servopulse" routine takes about 20 ms I'll call that routine
// twice for each of the 250 positions.

void sequence1(void) {
  unsigned char pos;
  // swing from left to right
  for(pos=0;pos<250;pos++) {
    servopulse(pos,pos);   
    servopulse(pos,pos);
  }
  // swing from right to left
  for (pos=250;pos>0;pos--) {
    servopulse(pos,pos);
    servopulse(pos,pos);
  }
}

// This second sequence will make the servos move in oposite directions. This time I want the swing
// to take about 2.5 seconds; If I'd stop at each of the 250 possible positions along the way
// I'd need to make each position hold for only 10ms. This is not possible because the "servopulse"
// routine takes about 20ms to run, so I'll simply skip steps.

void sequence2(void) {
  unsigned char pos;
  unsigned char pos2;
  // First swing
  for (pos=0;pos<250;pos=pos+2) {
    pos2=250-pos;
    servopulse(pos,pos2);
  }
  // Reverse swing
  for (pos=0;pos<250;pos=pos+2) {
    pos2=250-pos;
    servopulse(pos2,pos);
  }
}

main()
{
  TRISA = 0b11111001; // Make RA2 and RA1 outputs

  // Do the first sequence once
  sequence1();

  // Look pthe second sequence for ever
  while(1 == 1) sequence2();   

}

 


Get Your Ad Here