Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Programming (http://www.chiefdelphi.com/forums/forumdisplay.php?f=51)
-   -   quick question: TIMERS (http://www.chiefdelphi.com/forums/showthread.php?t=26637)

Xufer 10-03-2004 22:03

quick question: TIMERS
 
The code below works but i need just a few more loops in the code in order to get it to go exactly where i need it to any one know how i can make it start a new count after it gets past 254 so it doesnt loop, and i can add a few more steps to it, or does some one have a better way of doing this ? I got this way to work it just needs to run for a little bit longer.

Code:

void User_Autonomous_Code(void)
{
 int count;
 count = 1;
 while (autonomous_mode)  /* DO NOT CHANGE! */
 { 
    if (statusflag.NEW_SPI_DATA)      /* 26.2ms loop area */
    {
        Getdata(&rxdata);  /* DO NOT DELETE, or you will be stuck here forever! */
  /*40ticks = 1 sec 20ticks = .5 secs 10ticks=.25 secs */ //increse counter by 1 /* DO NOT DELETE, or you will get no PWM outputs! *//*40ticks = 1 sec 20ticks = .5 secs 10ticks=.25 secs */
 
  if ( count >= 124 ) {
  } 

  if (count > 0 && count < 34 )
  {
    pwm05 = 60;
      }
  if (count > 35 )
  {
    pwm05 = 127;
      }
  if (count > 0 && count < 30 )
  {
    pwm04 = 0;
      }
  if (count > 32 )
  {
    pwm04 = 127;
      }
  if (count > 35 && count < 90 )
  {
    pwm01 = 190;
      }
  if (count > 35 && count < 90 )
  {
    pwm02 = 190;
      }
  if (count > 92  && count <= 122)
  {
    pwm01 = 190;
  }
  if (count > 92 && count <= 122)
  {
    pwm02 = 53;
  }
  if (count > 130 && count < 160 )
  {
    pwm01 = 190;
      }
  if (count > 130 && count < 160 )
  {
    pwm02 = 190;
      }
  if (count > 163  && count <= 183)
  {
    pwm01 = 190;
  }
  if (count > 163 && count <= 183)
  {
    pwm02 = 53;
  }
  if (count > 223 && count < 250 )
  {
    pwm01 = 190;
      }
  if (count > 223 && count < 250 )
  {
    pwm02 = 190;
      }
  if (count > 255  && count <= 275)
  {
    pwm01 = 190;
  }
  if (count > 255 && count <= 275)
  {
    pwm02 = 53;
  }

  ++count; 
      Putdata(&txdata); 
  }
 }
}

any help would be greatly appreciated.

Tom Bottiglieri 10-03-2004 22:05

Re: quick question: TIMERS
 
you could just do an if of when it goes above the time.

if(timer>40)
{}
else if(timer>80)
{}

Daniel 10-03-2004 22:36

Re: quick question: TIMERS
 
Your code is begging to become a state machine. It is a codeing techinque that uses a switch statement and where each case is an independant state. This works well because of the 26.3 ms looping process. The benefit of state machines is that it can be written so that some states are re-entrant where they look for some event like time or distance to trigger the program into the next state.

switch (state) {
case 1 :
// start motors
t = time + SomeDiration
break;

case 2 :
if (time < t) // This is re-entrant.
state = 2;
else
state = 3;
break;

case 3 :
// stop motors and start next manuever...
...

Get the picture? It's not hard. It does require some thought. But this is how most very complex programs start out. There are other ways of doing this with pointers and trillions of function - but this is just so simple and readable.
If you are at the Great Lakes Competition look me up and I'll show you more.

Xufer 10-03-2004 22:36

Re: quick question: TIMERS
 
huh ? dun quite get it, too tired maybe ...

10intheCrunch 11-03-2004 02:06

Re: quick question: TIMERS
 
A few things:

At the most basic level, you don't need to worry about the int looping over. Ints in C are two byte variables; an unsigned one will store up to 32000+. If you need more than that, you can use long, which is a four byte variable.

Second, you don't need two seperate if statements when you are setting pwm01 and pwm02--they do the same thing, so put all the code you need in one! You'll save processing power and increase readability.

State machines can be a little confusing at first, but they will make your code much more readable in the end, and much faster. A state machine uses the switch command, which will look at one variable, and jump to the "case" that the variable number points to. So you would have an int variable to count another int variable that would be the state.

int count;
int state = 0;

void InitAuto(void){
count = 0;
//any other variables that you need to reset
}

void User_Auto_Code(void){
switch(state){ //look at the state variable for code to jump to

case 0:
//do some stuff
if(count > 100){
state++; //move to state 1
InitAuto();
}
break;

case 1:
//do some other stuff
if(count > 50){
state++; //move to state 2
InitAuto();
}
break;

etc etc etc....
}//close switch
count++;

As you can see, its really easy to make readable code this way, and you know exactly how many program counts are in each state without having to do any math =). This is also a much lighter load on your processor; your program will execute a lot faster and be cleaner in memory.

A couple symantic things: the break; statement is needed at the end of every case, to tell the compiler that you are done with the case. Just set up your cases in order, and tell your motors what to do =).

If you can implement real timers, it will make the program that much better (254 uses a millisecond timer), but you should be fine with the program counts.

Good luck!

Ryan M. 11-03-2004 06:06

Re: quick question: TIMERS
 
Quote:

Originally Posted by Xufer
huh ? dun quite get it, too tired maybe ...

Instead of stead of what you currently have, you'd put in something like his example. The basic idea is laid out below: (in semi-pseudo-code)
Code:

Static state variable starting at 0

switch(state variable)
{
    case 0:
        perform actions set 1
        check if this state is complete
            if it is, increment the state variable

    case 1:
        perform actions set 2
        check if this state is complete
            if it is, increment the state variable

    case 2:
        perform actions set 3
        check if this state is complete
            if it is, increment the state variable

    ...

    case X:
        don't do anything
}

By repeatedly calling this switch statement, it will work its way through all the states. You can, of course, also have statements in there that reset the statee variable, or put it to where ever you want.

Hope that clarifies it some.

Xufer 11-03-2004 14:23

Re: quick question: TIMERS
 
Quote:

Originally Posted by Texan
Instead of stead of what you currently have, you'd put in something like his example. The basic idea is laid out below: (in semi-pseudo-code)
Code:

Static state variable starting at 0

switch(state variable)
{
    case 0:
        perform actions set 1
        check if this state is complete
            if it is, increment the state variable

    case 1:
        perform actions set 2
        check if this state is complete
            if it is, increment the state variable

    case 2:
        perform actions set 3
        check if this state is complete
            if it is, increment the state variable

    ...

    case X:
        don't do anything
}

By repeatedly calling this switch statement, it will work its way through all the states. You can, of course, also have statements in there that reset the statee variable, or put it to where ever you want.

Hope that clarifies it some.

yea kind of but what tells it when a state is complete ? how would i say
case 1 is to happen for 2 seconds and case 2 is supposed to happen for 3 seconds?
pseudo of what im talking about :

case 1 for 2 seconds
pwm01= 200
pwm02= 200
pwm03= 150
pwm04= 200

then go to case 2

case 2 for 3 seconds
pwm01= 200
pwm02= 100

then go to case 3

case 3
pwm01= 200
pwm02= 200

etc . what keeps it with in time constraints and what cuases it to go to the next case statement.

10intheCrunch 11-03-2004 14:31

Re: quick question: TIMERS
 
That's all up in my post...

Make a "StateInit" function that runs everytime you move to a new state, that at the very least resets your count to 0. Put a count++; statement after the switch. Then, inside each case, say

if(count > someNumber){
StateInit();
state++;
}

That will move it to the next case when the count is above the number you want. Since you don't have a real timer you'll have to do the math yourself for how long to stay in each one but it shouldn't be that bad.

Xufer 11-03-2004 14:50

Re: quick question: TIMERS
 
Quote:

Originally Posted by 10intheCrunch
That's all up in my post...

Make a "StateInit" function that runs everytime you move to a new state, that at the very least resets your count to 0. Put a count++; statement after the switch. Then, inside each case, say

if(count > someNumber){
StateInit();
state++;
}

That will move it to the next case when the count is above the number you want. Since you don't have a real timer you'll have to do the math yourself for how long to stay in each one but it shouldn't be that bad.

If you do that wont the count everflow after it reaches 254 ? whats to keep it from doing that ? Im still kind of missing it i guess. Or how would i make a real timer i mean i treid experimenting with one but i failed.

10intheCrunch 11-03-2004 15:09

Re: quick question: TIMERS
 
Again...read my post...

If you use an int for your counter variable, you will have more than enough space. An int in C is a two byte variable, meaning the signed version can store from -32000 to 32000.

What you're thinking about is a char, a one byte variable. That will turn over at 254 (or 128 if it is signed).

Have you tested your code yet?

Xufer 11-03-2004 15:12

Re: quick question: TIMERS
 
Quote:

Originally Posted by 10intheCrunch
Again...read my post...

If you use an int for your counter variable, you will have more than enough space. An int in C is a two byte variable, meaning the signed version can store from -32000 to 32000.

What you're thinking about is a char, a one byte variable. That will turn over at 254 (or 128 if it is signed).

Have you tested your code yet?


so what if i use my orrigianl code and just change char to int then i wont have to eorry about the overflow problem right ?

Ryan M. 11-03-2004 15:16

Re: quick question: TIMERS
 
Quote:

Originally Posted by Xufer
yea kind of but what tells it when a state is complete ? how would i say
case 1 is to happen for 2 seconds and case 2 is supposed to happen for 3 seconds?
pseudo of what im talking about :

case 1 for 2 seconds
pwm01= 200
pwm02= 200
pwm03= 150
pwm04= 200

then go to case 2

case 2 for 3 seconds
pwm01= 200
pwm02= 100

then go to case 3

case 3
pwm01= 200
pwm02= 200

etc . what keeps it with in time constraints and what cuases it to go to the next case statement.


You could have a variable that gets increment every 26.2ms. If this functions is getting called that often, it could be static to it. If not, it could be a global variable that is incremented in something that is. Then, for the tests, you would check if the variable was greater than, say, 78. This would make it run for approzimately 2 second ((1000ms/26.2ms)*x seconds). Or, if you need more accuracy than that, and that's not bad, you can have an external clock attched to pin 1/2 and have an interrunpt that increments it.

10intheCrunch 11-03-2004 15:40

Re: quick question: TIMERS
 
Quote:

Originally Posted by Xufer
so what if i use my orrigianl code and just change char to int then i wont have to eorry about the overflow problem right ?

Your original code does use int instead of char, but yes. You shouldn't have any overflow problem.

jacob_dilles 11-03-2004 16:00

Re: quick question: TIMERS
 
Quote:

Originally Posted by Texan
you can have an external clock attched to pin 1/2 and have an interrunpt that increments it.

doesnt the pic have like 3 built in timers?

Astronouth7303 11-03-2004 17:18

Re: quick question: TIMERS
 
5: 0-4. 0 is used by FRC_library.lib and is slowest of all, 1&3 are faster than 2&4.
Range: (Prescaler Range|Postscaler Range)
0: 1:2-1:256|1:1
1: 1:1-1:8|1:1
2: 1:1-1:16|1:1-1:16
3: 1:1-1:8|1:1
4: 1:1-1:16|1:1-1:16
The prescalers are powers of 2 (*2), and postscalers are integers (+1). The base frequincies of all the timers is the same: w/o scaling they are 10MHz clocks and a 100ns tick.

This all out of Kevin's interupt.c file. WELL commented

Ryan M. 11-03-2004 18:36

Re: quick question: TIMERS
 
Yes, it does have timers (4), but I couldn't figure out how to use them, and didn't feel the need to try much. If someone knows how, those would also work.

Kevin Watson 11-03-2004 23:14

Re: quick question: TIMERS
 
Quote:

Originally Posted by Texan
Yes, it does have timers (4), but I couldn't figure out how to use them, and didn't feel the need to try much. If someone knows how, those would also work.

Have a look at the two clock programs that I wrote and posted here. Comments within the code will show you where to place your own test code. If you run into problems, just leave a note here and we'll help you out.

-Kevin

Astronouth7303 12-03-2004 07:35

Re: quick question: TIMERS
 
I have had problems with interupts.c and timers. I use Timer 2 (and/or 1) to increment a variable and if that variable overflows, it increments another one. The problem is that I can't ever seem to get either to change. Help?

Mark McLeod 12-03-2004 10:00

Re: quick question: TIMERS
 
Quote:

Originally Posted by Astronouth7303
I have had problems with interupts.c and timers. I use Timer 2 (and/or 1) to increment a variable and if that variable overflows, it increments another one. The problem is that I can't ever seem to get either to change. Help?

Sounds like the timers haven't been enabled in your initialization code.

Here's a sample initialization of Timer 4 to cause a 4ms interrupt.
Code:

OpenTimer4(TIMER_INT_ON &
          T4_PS_1_16 &
          T4_POST_1_10);
WriteTimer4(6); /* Preload timer to overflow after 4ms */

Here's the corrsponding user_routines_fast.c interrupt code.
Code:

unsigned long Clockms; // 1 millisecond clock
unsigned long Clockcs; // 100 millisecond
unsigned long Clocksec; // 1 second clock
 
static unsigned char t100ms=0;
static unsigned int t1sec=0;
 
...
 
else if (PIR3bits.TMR4IF) /* TIMER 4 INTERRUPT */
{
  /** This provides us with a clock for timing events **/
  PIR3bits.TMR4IF = 0; /* Clear Timer interrupt flag */
  WriteTimer4(6);        /* Reset Timer to overflow at 4ms */
  Clockms += 4; /* milliseconds */
  if (++t100ms >= 25)
  {
        t100ms = 0;
        Clockcs++; /* tenths of seconds */
        if (++t1sec >= 10)
        {
          t1sec = 0;
          Clocksec++; /* seconds */
        }
  }
}


10intheCrunch 12-03-2004 10:29

Re: quick question: TIMERS
 
Quote:

Originally Posted by Astronouth7303
I have had problems with interupts.c and timers. I use Timer 2 (and/or 1) to increment a variable and if that variable overflows, it increments another one. The problem is that I can't ever seem to get either to change. Help?

Why not just use a long? You won't overflow it (depending on the timer you use you'll have a couple thousand hours of timer before the long cycles).

Xufer 12-03-2004 11:20

Re: quick question: TIMERS
 
now if i was to use the timers that kevin has on his site inorder to do a dedreckoning autonomus what would it look like ? I begin to have a little more trouble when the interrupts are thrown in there i looked through the actuall clock.c file and the user_routines_fast.c file how would i specify time lengths for an action ? Im not too sure how the interupts work i read the first white paper on them but my understanding of them are still kinda wavy.

Mark McLeod 12-03-2004 11:42

Re: quick question: TIMERS
 
Quote:

Originally Posted by Xufer
now if i was to use the timers that kevin has on his site inorder to do a dedreckoning autonomus what would it look like ? I begin to have a little more trouble when the interrupts are thrown in there i looked through the actuall clock.c file and the user_routines_fast.c file how would i specify time lengths for an action ? Im not too sure how the interupts work i read the first white paper on them but my understanding of them are still kinda wavy.

In Kevin's examples you can use the "Clock" variable as your check.
e.g.,
Code:

if (Clock < 10) // Clock is in tenths of seconds
        // Do first thing
else if (Clock < 30) // @ 3 second
        // Do another thing
else if (Clock < 60) // @ 6 seconds
        // Keep adding stuff to do
.
.
.
else if (Clock < 150) // @ 15 seconds
        // Make sure you stop all engines at the end

There are lots of other autonomous examples spread through the forums.

[edit] Corrected the ">" , typed too freely. Thanks Jamie!

Astronouth7303 12-03-2004 13:49

Re: quick question: TIMERS
 
The timer (1-4, actually) is initialized, and I have checked the enabled bit. The overflow variable (a char) is to slow it down. I send the long both over the terminal and through the dashboard. Both always say 0. The code looks like it should work, but doesn't. This is my ISR:
Code:

extern char TICK;
extern long TIME;
extern long AUTOCLOCK;

void Timer_1_Int_Handler(void)
{
 TICK++;
 if (TICK == 255)
 {  TIME++; }
 AUTOCLOCK++;
}

Also, have "Clock > 150" first and "Clock > 0" last (Descending order), I found this out in some EDU trials. "Clock > 0" will be true if "Clock > 150", so if >0 is before >150, >150 never happens because >0 does.

jacob_dilles 12-03-2004 14:35

Re: quick question: TIMERS
 
make sure its not only enabled, but i think you have to start it too

Xufer 12-03-2004 15:22

Re: quick question: TIMERS
 
i got kevins interrupt code and i looked through it, how do i call one of the timers to start counting ? then how would i implement it into autonomus ?

10intheCrunch 12-03-2004 15:27

Re: quick question: TIMERS
 
Call the start method in the User_Initialization function (Timer2Start() or Timer4Start() or whatever it is). Then, use the state machines that we told you about in the first page of this thread. In the StateInit() function, set a new variable like StartTime or something to keep track of where the timer was when you moved into the next state. Then just subtract the start from the actual, and when that value is larger than the one you want (how long you want to stay in the state), move to the next state and call the Init function.

Astronouth7303 12-03-2004 18:02

Re: quick question: TIMERS
 
Initialize_Timer_X, And you have to modify the line that reads: TxCONbits.TMRxON = 0; to TxCONbits.TMRxON = 1;, else the timer won't go.

Mark McLeod 12-03-2004 19:28

Re: quick question: TIMERS
 
Quote:

Originally Posted by Astronouth7303
The timer (1-4, actually) is initialized, and I have checked the enabled bit. The overflow variable (a char) is to slow it down. I send the long both over the terminal and through the dashboard. Both always say 0. The code looks like it should work, but doesn't. This is my ISR:
Code:

extern char TICK;
extern long TIME;
extern long AUTOCLOCK;
 
void Timer_1_Int_Handler(void)
{
TICK++;
if (TICK == 255)
{ TIME++; }
AUTOCLOCK++;
}


Fixed my earlier post. Thanks for noticing my error.

Your code looks file of course.
Have you tried displaying TICKS on the dashboard or terminal to see if it is also not getting incremented?
I have to run now, but I'll be back later and try to duplicate what you did in a test program.

Astronouth7303 12-03-2004 20:00

Re: quick question: TIMERS
 
Quote:

Originally Posted by Mark McLeod
Your code looks file of course.
Have you tried displaying TICKS on the dashboard or terminal to see if it is also not getting incremented?
I have to run now, but I'll be back later and try to duplicate what you did in a test program.

Not incrementing. Here's the declarations (In Variables.h, which is included in Interupts.c)
Code:

extern long TIME;
extern long AUTOCLOCK;
extern char TICK;

They are actually defined in Variables.c.

The User_Routines_Fast.c Interuptor (Actually executed by proc) is this, just to check:
[code]#pragma code InterruptVectorLow = LOW_INT_VECTOR

void InterruptVectorLow (void)
{
_asm
goto InterruptHandlerLow // jump to InterruptHandlerLow()
_endasm
}

#pragma code

//...

#pragma interruptlow InterruptHandlerLow save=PROD,section("MATH_DATA"),section(".tmpdata")

void InterruptHandlerLow()
{
//...
}[/check]

I didn't edit this (to my knowledge :yikes:), so I can't imagine that would be it. The code is compiling fine, no errors or warnings.

jacob_dilles 12-03-2004 20:03

Re: quick question: TIMERS
 
Quote:

Originally Posted by Astronouth7303
Initialize_Timer_X, And you have to modify the line that reads: TxCONbits.TMRxON = 0; to TxCONbits.TMRxON = 1;, else the timer won't go.

this is what im talking about. just set TxCONbits.TMRxON = 1 when you want it to start, and TxCONbits.TMRxON = 0 when you want it to stop. if you put this line outside of the while(auton) loop (before and after respectivly), it will work perfectly

Astronouth7303 12-03-2004 20:16

Re: quick question: TIMERS
 
I just relized something. In the initialize routines for the timers, the first 2 lines are address setters (I think). Most of mine are 0x00! Does this make a difference?

Mark McLeod 12-03-2004 22:21

Re: quick question: TIMERS
 
Quote:

Originally Posted by Astronouth7303
I just relized something. In the initialize routines for the timers, the first 2 lines are address setters (I think). Most of mine are 0x00! Does this make a difference?

No. Those just mean the timer starts at 0.

Believe I found the problem.
TICKS is declared as char (-127 to 127)
You are checking for 255 as an overflow.
TIME will never increment.


I grabbed Kevins interrupt code and added your code to the interrupt handler.
Only difference is I just declared your globals as static just within interrupts.c for my ease of duplicating your results.

TICKS and AUTOCLOCK increment as you wanted.

In Initialize_Timer_1 I changed:
Code:

PIE1bits.TMR1IE = 1;
T1CONbits.TMR1ON = 1;


Xufer 12-03-2004 22:47

Re: quick question: TIMERS
 
before i enable one of those timers, is there anythign i should know about which one would work best are there significant differences for them, i noticed you can change the ammount of time each tick increses the clock by.

once i enable one im still confused as far as the state switches and the case statements, idon't understand how the whole thing works is there any documentation or sample code i can look through, im really stumped and i would like to get a timer working.

10intheCrunch 13-03-2004 22:58

Re: quick question: TIMERS
 
OK...I really want to help you dude but it seems like you don't understand what we're trying to say each time, or I can't explain it well enough...why don't you IM me (sn: TenintheCrunch)? I think I'll be able to help you more talking directly :)

Cheers,

Astronouth7303 15-03-2004 07:29

Re: quick question: TIMERS
 
I changed a compiler option to assume Char is unsigned. I only use a signed char one place, -1 - 1, and it's declared as signed. I also sent TICK to dashboard, and it didn't work. I didn't have IE set to 1, but I didn't think it would make a difference (it would just be slower, right?)

10intheCrunch 15-03-2004 10:14

Re: quick question: TIMERS
 
Where's the option for making chars unsigned by default? Does that affect ints and longs as well?

Mark McLeod 15-03-2004 10:36

Re: quick question: TIMERS
 
Quote:

Originally Posted by 10intheCrunch
Where's the option for making chars unsigned by default? Does that affect ints and longs as well?

You set compiler flags in MPLAB
Project->Build Options...->Project
under tab "MPLAB C18"

There is a quick radio button for treating "char" as unsigned and one for forcing all calculations to be performed at least as int rather than the smallest type included in the calculation.
You can also enter your own flags by clicking on "Use Alternate Settings" and typing into the box that becomes enabled. You'll find the available compiler flags documented in the MPLAB C18 C Compiler User's Guide that came on the MPLAB installation CD, Appendix C. e.g., -k is the flag for treating char as unsigned. When you click on the radio button you'll see "-k" appear in the "Inherit global settings" window.

Mark McLeod 15-03-2004 10:41

Re: quick question: TIMERS
 
Quote:

Originally Posted by Astronouth7303
I didn't have IE set to 1, but I didn't think it would make a difference (it would just be slower, right?)

If you mean:
INTCON3bits.INT2IE = 1;
Yes, this is required. It's your on/off switch for individual interrupts. It enables the interrupt which is disabled by default. Otherwise, nothing will happen.

Astronouth7303 15-03-2004 11:24

Re: quick question: TIMERS
 
Banner interupts work, but not timers.

Mark McLeod 15-03-2004 11:49

Re: quick question: TIMERS
 
Quote:

Originally Posted by Astronouth7303
Banner interupts work, but not timers.

Sorry I mistyped and used the external interrupt flag. I meant to type:
Code:

PIE1bits.TMR1IE = 1;
This is required to turn on interrupt on timer overflow.

Xufer 15-03-2004 16:23

Re: quick question: TIMERS
 
i got my ded reckoning worked out and i have a switch wired up to switch between the two modes how would i do that using case statements?

it should be something like


case1 if (rc_dig_in_10=1)
{auton 1}

case2 else(rc_dig_in10=0)
{auton 2}

i read about them but how would they be used to work with a digital input from the rc

Mark McLeod 15-03-2004 16:48

Re: quick question: TIMERS
 
Quote:

Originally Posted by Xufer
i got my ded reckoning worked out and i have a switch wired up to switch between the two modes how would i do that using case statements?

it should be something like


case1 if (rc_dig_in_10=1)
{auton 1}

case2 else(rc_dig_in10=0)
{auton 2}

i read about them but how would they be used to work with a digital input from the rc

You don't need a case statement if you only have two choices.
Code:

if (rc_dig_in_10 == 1)  //or just "if (rc_dig_in_10)"
{auton 1}
else
{auton2}


Xufer 15-03-2004 23:26

Re: quick question: TIMERS
 
Quote:

Originally Posted by Mark McLeod
You don't need a case statement if you only have two choices.
Code:

if (rc_dig_in_10 == 1)  //or just "if (rc_dig_in_10)"
{auton 1}
else
{auton2}


will that work if my autonmode begins in if statements though ? i tried something along those lines and it didnt seem to work...

Mark McLeod 16-03-2004 10:37

Re: quick question: TIMERS
 
Quote:

Originally Posted by Xufer
will that work if my autonmode begins in if statements though ? i tried something along those lines and it didnt seem to work...

It will work.
If you try it and it doesn't behave as you expect post the error here and we'll help you debug any problems.

10intheCrunch 16-03-2004 13:26

Re: quick question: TIMERS
 
Quote:

Originally Posted by Xufer
i got my ded reckoning worked out and i have a switch wired up to switch between the two modes how would i do that using case statements?

it should be something like


case1 if (rc_dig_in_10=1)
{auton 1}

case2 else(rc_dig_in10=0)
{auton 2}

i read about them but how would they be used to work with a digital input from the rc

You don't need to use case statements, but there are a couple other things you have to do.

When you enter autonomous mode, all inputs are reset to neutral, so you have to capture the value from rc_dig_in_10 before autonomous turns on. Create a prevRcDigIn10 variable, and set that equal to the current one at the end of every loop (right before putdata()), then when you move into autonomous, look at that previous varialbe, not the real one (the "real" one will always be zero).

Astronouth7303 16-03-2004 13:49

Re: quick question: TIMERS
 
Huh? You are talking about the IO on the RC, right? In auto mode, the OI transmits inputs as neutural.

Xufer 16-03-2004 14:48

Re: quick question: TIMERS
 
so it would be like:

#define digin10old

then later on ....

digin10old = (rc_dig_in10)
putdata()

Alan Anderson 16-03-2004 16:10

Re: quick question: TIMERS
 
Quote:

Originally Posted by Xufer
so it would be like:

#define digin10old

then later on ....

digin10old = (rc_dig_in10)
putdata()

No, it would not be like that, for a whole bunch of reasons.

Contrary to an earlier post, the RC inputs such as rc_dig_in10 do work during autonomous mode, so there's no reason to do it this way. The advice to save the values for later use applies only to OI inputs (knobs and switches, mostly) that you want to use to configure autonomous operation.

Also, variables in c aren't declared using #define statements. The proper syntax is not trivial, but it is not important here, since you don't need to use a variable for this purpose.

Xufer 16-03-2004 17:56

Re: quick question: TIMERS
 
so it would be done how then ?

Alan Anderson 16-03-2004 19:02

Re: quick question: TIMERS
 
Quote:

Originally Posted by Xufer
so it would be done how then ?

It would be done the way Mark McLeod explained back in response #42, testing the digital input with a simple if statement.

Xufer 17-03-2004 13:20

Re: quick question: TIMERS
 
Code:

if (rc_dig_in18=1)        {

                        if (cnttick < 34 )
                        {
                                pwm05 = 60;
                                  }
                        if (cnttick > 35 )
                        {
                                pwm05 = 127;
                                  }
                        if (cnttick < 30 )
                        {
                                pwm04 = 0;
                                  }
                        if (cnttick < 32 )
                        {
                                pwm04 = 127;
                                  }
//raises arm up for 40 ticks 1 second(s) /\ /\

// drive motors from here on out \/  \/
                       
                        if (cnttick > 35 && cnttick < 90 )
                        {
                                pwm01 = 190;
                                  }

                        if (cnttick > 35 && cnttick < 90 )
                        {
                                pwm02 = 190;
                                  }
                        if (cnttick > 92  && cnttick <= 122)
                        {
                                pwm01 = 190;
                        }

                        if (cnttick > 92 && cnttick <= 122)
                        {
                                pwm02 = 53;
                        }
                        if (cnttick > 130 && cnttick < 160 )
                        {
                                pwm01 = 190;
                                  }

                        if (cnttick > 130 &&  cnttick < 160)
                        {
                                pwm02 = 190;
                          }
                        if (cnttick > 163  && cnttick <= 183)
                        {
                                pwm01 = 190;
                        }

                        if (cnttick > 163 && cnttick <= 183)
                        {
                                pwm02 = 53;
                        }
                        if (cnttick > 223 && cnttick < 250 )
                        {
                                pwm01 = 190;
                                  }

                        if (cnttick > 223 && cnttick < 250 )
                        {
                                pwm02 = 190;
                          }
                        if (cnttick > 255  && cnttick <= 275)
                        {
                                pwm01 = 190;
                        }

                        if (cnttick > 255 && cnttick <= 275)
                        {
                                pwm02 = 53;
                        }

}

else {
                        pwm01=210;
}

when i do it like that reguardless of the switch it always works like the switch is on even when its off.

10intheCrunch 17-03-2004 13:29

Re: quick question: TIMERS
 
Quote:

Contrary to an earlier post, the RC inputs such as rc_dig_in10 do work during autonomous mode, so there's no reason to do it this way. The advice to save the values for later use applies only to OI inputs (knobs and switches, mostly) that you want to use to configure autonomous operation.
My mistake. Sorry to confuse...

Your code seems ok at first glance...why don't you put this statement in your Process_data function:

printf("%d\n", (int)rc_dig_in18);

Check the console printout while your program cable is plugged in. Make sure that it changes properly with the switch on your robot.

Too improve efficiency: use else if statements. For example:

if(ticks < 15)
blah;
else if (ticks < 35)
blah;

That will handle your decisions faster...

Sorry again if I confused you eariler. :)

Xufer 17-03-2004 13:36

Re: quick question: TIMERS
 
Quote:

Originally Posted by 10intheCrunch
My mistake. Sorry to confuse...

Your code seems ok at first glance...why don't you put this statement in your Process_data function:

printf("%d\n", (int)rc_dig_in18);

Check the console printout while your program cable is plugged in. Make sure that it changes properly with the switch on your robot.

Too improve efficiency: use else if statements. For example:

if(ticks < 15)
blah;
else if (ticks < 35)
blah;

That will handle your decisions faster...

Sorry again if I confused you eariler. :)

i stuck in the printf statement and it shows the switch on and off depending on the position, so i know its not the switch its something i did.

pink967 17-03-2004 13:50

Re: quick question: TIMERS
 
you guys are all really smart...i need to learn this stuff, or else i don't get to be on my team next year

Alan Anderson 17-03-2004 14:07

Re: quick question: TIMERS
 
Quote:

Originally Posted by Xufer
Code:

if (rc_dig_in18=1)        {
when i do it like that reguardless of the switch it always works like the switch is on even when its off.

That's because you've fallen into a common trap with the c language's syntax. Testing for equality is done with the == "is equal" operator, and you've instead used the = "assignment" operator. Your code assigns the value "1" to the variable "rc_dig_in18", and then tests the result -- which is always 1, interpreted as true by the software.

What your first line should say instead is this:
Code:

if (rc_dig_in18==1)        {
Or you could leave off the explicit test for 1, and let c's boolean rules work for you:
Code:

if (rc_dig_in18)        {
That should take care of the problem you're having.

Xufer 17-03-2004 21:37

Re: quick question: TIMERS
 
Quote:

Originally Posted by Alan Anderson
That's because you've fallen into a common trap with the c language's syntax. Testing for equality is done with the == "is equal" operator, and you've instead used the = "assignment" operator. Your code assigns the value "1" to the variable "rc_dig_in18", and then tests the result -- which is always 1, interpreted as true by the software.

What your first line should say instead is this:
Code:

if (rc_dig_in18==1)        {
Or you could leave off the explicit test for 1, and let c's boolean rules work for you:
Code:

if (rc_dig_in18)        {
That should take care of the problem you're having.

mmk thnx, but j/w how would i do it if i was to have like 4 auton modes i have a sitch box that will occupy 6 dig_in's

Astronouth7303 18-03-2004 07:28

Re: quick question: TIMERS
 
Quote:

Originally Posted by Xufer
mmk thnx, but j/w how would i do it if i was to have like 4 auton modes i have a sitch box that will occupy 6 dig_in's

Four modes and six dig ins? To do four modes, you only need 2! With 6, you can have 64 modes!

Alan Anderson 18-03-2004 08:42

Re: quick question: TIMERS
 
Quote:

Originally Posted by Xufer
...how would i do it if i was to have like 4 auton modes...

You have a couple of options. Simplest in your case would probably be to do something like this:
Code:

// somehow get a number in the "auto" variable
  auto = (rc_dig_in18<<2) | (rc_dig_in17<<1) | (rc_dig_in16);
// or whatever it takes to turn your switches into a value
  if (auto==1)
  {
    // code for mode 1
  }
  if (auto==2)
  {
    // code for mode 2
  }
  // etc.

It might theoretically be more efficient to use a switch/case statement instead of a string of ifs, but you probably have enough to focus on right now without worrying about learning another control structure.

Ryan M. 18-03-2004 08:49

Re: quick question: TIMERS
 
Quote:

Originally Posted by Astronouth7303
Four modes and six dig ins? To do four modes, you only need 2! With 6, you can have 64 modes!

Just to show what he means:
Code:

      On  Off
sw1  1      2
sw2  3      4

Where sw1 and sw2 are the two switches and the numbers in the center are the automous modes.


All times are GMT -5. The time now is 12:47.

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