Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Programming (http://www.chiefdelphi.com/forums/forumdisplay.php?f=51)
-   -   Thanks for all your help...and a question (http://www.chiefdelphi.com/forums/showthread.php?t=51341)

brennerator 09-01-2007 02:33

Thanks for all your help...and a question
 
Quick question

I have the 2006 default code loaded up.

If I wanted the trigger (fire) button on the 1 joystick controlling the robot movement to reduce the robots speed to 50% how would I do that.

I tried:

if (p1_sw_trig == 0)
{
pwm13 = pwm14 = Limit_Mix(2000 + p1_y + p1_x - 127);
pwm15 = pwm16 = Limit_Mix(2000 + p1_y - p1_x + 127);
}
else
{
pwm13 = (pwm13-127)*0.5+127;
pwm14 = (pwm14-127)*0.5+127;
pwm15 = (pwm15-127)*0.5+127;
pwm16 = (pwm16-127)*0.5+127;
}


but when the trigger was pressed nothing moved on teh robot!

Any help?

Tottanka 09-01-2007 03:21

Re: Thanks for all your help...and a question
 
i dont know what u ment to do...
Dom you want the robot to move at 50% of its speed when u press the trigger and thats it? or do u also move the joystics Y farward?

brennerator 09-01-2007 03:24

Re: Thanks for all your help...and a question
 
Basically; I want the joysticks to be waay less sensitive when i press the button. I basically want the speed to be halved at every point when the joystick moves.

Tottanka 09-01-2007 03:27

Re: Thanks for all your help...and a question
 
oh i get it...
i havent toucked programming for a year but i can tell you what i'd do:
if (p1_sw_trig == 0) && (p1_y==1)
{

pwm13=pwm14=pwm15=pwm16=(127+0.5*127);
}
else if (p1_sw_trig == 0) && (p1_y==-1)
{

pwm13=pwm14=pwm15=pwm16=(127-0.5*127);
}

bear24rw 09-01-2007 08:16

Re: Thanks for all your help...and a question
 
Quote:

Originally Posted by Tottanka (Post 551942)
oh i get it...
i havent toucked programming for a year but i can tell you what i'd do:
if (p1_sw_trig == 0) && (p1_y==1)
{

pwm13=pwm14=pwm15=pwm16=(127+0.5*127);
}
else if (p1_sw_trig == 0) && (p1_y==-1)
{

pwm13=pwm14=pwm15=pwm16=(127-0.5*127);
}

When would p1_y ever be -1?

Alan Anderson 09-01-2007 09:29

Re: Thanks for all your help...and a question
 
Your code never reads the joysticks if the button is pressed, so it repeatedly divides the pwm values by two until it decays to zero. That's why the robot stops moving.

Try moving the part that reads the joysticks outside the test for the button.
Code:

  pwm13 = pwm14 = Limit_Mix(2000 + p1_y + p1_x - 127);
  pwm15 = pwm16 = Limit_Mix(2000 + p1_y - p1_x + 127);

  if (p1_sw_trig == 1)
  {
    pwm13 = (pwm13-127)/2+127;
    pwm14 = (pwm14-127)/2+127;
    pwm15 = (pwm15-127)/2+127;
    pwm16 = (pwm16-127)/2+127;
  }

It's safe to do it this way because the pwm values don't actually take effect until the Generate_PWMs() call at the end of Process_Data_From_Local_IO().

By the way, if you plan to use timers and serial communication and encoders and other interrupt-based stuff, avoiding pwms 13-16 would be a good idea. They're generated by the user processor and can get somewhat twitchy when interrupts are happening often. Put your motor controls on pwms 1-12 if you want to keep things easy.

(Note that I replaced the multiply by 0.5 with a divide by 2. Keeping everything as integers makes sure that the compiler doesn't try to do floating point calculations, which take up a lot more time and program space.)

Kevin Sevcik 09-01-2007 10:00

Re: Thanks for all your help...and a question
 
Question to Alan (or anyone),

I'm under the impression a >>1 instead of a /2 would work there and would (possibly?) be faster. We've tried this in some spots in code before, however, and I think it corrupts signed variables. Do you (or anyone) have any specific knowledge about the >> operator on this PIC? I was sort of hoping that it or some other operator will do a signed >> operation and carry the signed bit.

brennerator 09-01-2007 12:42

Re: Thanks for all your help...and a question
 
Thanks a lot guys; Ill try this out today!

Eclipse 09-01-2007 15:46

Re: Thanks for all your help...and a question
 
Quote:

Originally Posted by Alan Anderson (Post 552013)
(Note that I replaced the multiply by 0.5 with a divide by 2. Keeping everything as integers makes sure that the compiler doesn't try to do floating point calculations, which take up a lot more time and program space.)

Something else to keep in mind when dealing with data types is that, from experience, the default printf function seems to not like to deal with floating point numbers. I have no idea if it can be modified to change that or if anyone's done that already.....

darist 10-01-2007 22:08

Re: Thanks for all your help...and a question
 
Quote:

Originally Posted by Kevin Sevcik (Post 552033)
Question to Alan (or anyone),

I'm under the impression a >>1 instead of a /2 would work there and would (possibly?) be faster. We've tried this in some spots in code before, however, and I think it corrupts signed variables. Do you (or anyone) have any specific knowledge about the >> operator on this PIC? I was sort of hoping that it or some other operator will do a signed >> operation and carry the signed bit.

The ">>" in C is the "shift right bitwise" operation. Because of the fact that microprocessors use the binary number system (0s and 1s) a "shift right" results in the same thing as "divide by 2 (but throw away the remainder)."

I was looking throug the MCC18 (Microchip's C compiler) User Guide and found this in Appendix B.4:

Quote:

ANSI C Standard: “The result of a right shift of a negative-valued signed integral type (6.3.7).”
Implementation: The value is shifted as if it were an unsigned integral type of the same size (i.e., the sign bit is not propagated).
Sounds to me like the MCC18 compiler does not have a way to make ">>" operate on signed integers.

Good luck!

tseres 07-06-2007 12:14

Re: Thanks for all your help...and a question
 
make a function for it

[from regular code]

if(p1_sw_trig){
dim_down(pwm01);
}

unsigned char dim_down(int input,float factor){
input-=127;
input*=factor //the factor to dim down the output
return input;
}

Salik Syed 08-06-2007 19:12

Re: Thanks for all your help...and a question
 
It won't work on signed integers, because in order to have fast add and subtract between positive integers most procecssors use a twos complement system.
Basically there is a sign bit, and if the bit is enabled then you reverse the 1 for a 0, so if a number is negative it is instead represented by it's not'd equivalent

So -2 would be
11111110 (for an 8 bit signed char)
The most significant bit is the sign bit.

Now lets try adding -2 to 3:
00000011
11111110
---------
00000001

Tada ..
The extra bit overflows and is discarded... so we can use the same logic adding positive and negative numbers together ... yay!


When you try to bit shift a signed int this is what may happen:
11111100 (-3)
becomes 01111110 (126)

You can still bit shift but the sign bit needs to be replaced... you can do this by XORing the result with 10000000



I actually don't think dividing by two using the bit shift operator really matters, most optimizing compilers should realize that an unsigned int is being divided by two and just swap that in at the assembly level. Secondly most first applications I have seen don't even come close to being computationally intensive enough to warrant such an optimization.
(I don't know if this is actually what happens when using MC18 or whatever it's called)

BTW: for printf I think you can just use %f to print floats

Quzarx 13-06-2007 03:43

Re: Thanks for all your help...and a question
 
Quote:

if (p1_sw_trig == 0)
{
pwm13 = pwm14 = Limit_Mix(2000 + p1_y + p1_x - 127);
pwm15 = pwm16 = Limit_Mix(2000 + p1_y - p1_x + 127);
}
else
{
pwm13 = (pwm13-127)*0.5+127;
pwm14 = (pwm14-127)*0.5+127;
pwm15 = (pwm15-127)*0.5+127;
pwm16 = (pwm16-127)*0.5+127;
}
The way this is set up, you are only getting data from the joysticks when the trigger is not on. You always want to get that data, so first, take
pwm13 = pwm14 = Limit_Mix(2000 + p1_y + p1_x - 127);
pwm15 = pwm16 = Limit_Mix(2000 + p1_y - p1_x + 127);
out of the if block, so that you get new data from the joysticks every loop.
Then, if the trigger is on, you want to divide by 2, not multiply by a decimal

Code:

pwm13 = pwm14 = Limit_Mix(2000 + p1_y + p1_x - 127);
pwm15 = pwm16 = Limit_Mix(2000 + p1_y - p1_x + 127);
if (p1_sw_trig == 1)
{
pwm13 = (pwm13-127)/2+127;
pwm14 = (pwm14-127)/2+127;
pwm15 = (pwm15-127)/2+127;
pwm16 = (pwm16-127)/2+127;
}

Because you are getting the data every loop, and the pwm values aren't set until the end of the loop, you can modify them all you want before that point. Previously, you when the trigger was enabled, you were taking the pwm value, which defaults to 127, subtracting 127, making it 0, multiplying that by .5, making it 0 again, and adding 127, making it neutral on the motors.

Another way to do this would be:

Code:

if (p1_sw_trig == 0)
{
pwm13 = pwm14 = Limit_Mix(2000 + p1_y + p1_x - 127);
pwm15 = pwm16 = Limit_Mix(2000 + p1_y - p1_x + 127);
}
else
{
pwm13 = pwm14 = (Limit_Mix(2000 + p1_y + p1_x - 127)-127)/2+127;
pwm15 = pwm 16 (Limit_Mix(2000 + p1_y - p1_x + 127)-127)/2+127;
}

In this case, you are getting the data from the joysticks in both if and else.

seanl 13-06-2007 10:03

Re: Thanks for all your help...and a question
 
if(p1_sw_trig == 1)
{
pwm13=pwm14=(p1_y/2);
pwm15=pwm16=(p2_y/2);
}
else
{
pwm13=pwm14=(p1_y);
pwm15=pwm16=(p2_y);
}

isnt it as simple as that.

fimmel 13-06-2007 13:49

Re: Thanks for all your help...and a question
 
Quote:

Originally Posted by seanl (Post 631640)
if(p1_sw_trig == 1)
{
pwm13=pwm14=(p1_y/2);
pwm15=pwm16=(p2_y/2);
}
else
{
pwm13=pwm14=(p1_y);
pwm15=pwm16=(p2_y);
}

isnt it as simple as that.

that would work for "tank style" drive, i think he meant using a single stick drive.


All times are GMT -5. The time now is 03:29.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi