Go to Post [on practice robots:] Twice the work and twice the practice building seem to equal twice the experience so far. - MrBasse [more]
Home
Go Back   Chief Delphi > Technical > Technical Discussion
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Closed Thread
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 03-08-2010, 17:22
siaohuang siaohuang is offline
Registered User
no team
 
Join Date: Aug 2010
Location: Fort Wayne IN
Posts: 10
siaohuang is an unknown quantity at this point
Delay10KTCYx in C18

Hello everyone I'm back again,

First of I would like to thank all who has helped me out on the recent question, and yet I'm here to bug you guys again...

Currently I'm using mplab v7.60 C18 v2.40 I've successfully built VexUserCode.mcw right now I would like to run my robot autonomously

I'm under the "user_routines_fast.c" and I was trying to program my robot to go straight for 5 seconds and stop using the Delay10KTCYx function in "delay.h" I tried with the code below, how did I come up with the 5000?

my chip is PIC18f8520 and I check the datasheets the Fosc is 40MHz

so Delay10KTCYx (5000); // should give me a delay of 10000 x 5000 x 4/40M = 5 seconds

and after 5 seconds I want it to stop so I added

pwm02=127;
pwm03=127;

is there something wrong with my code or am I using the Delay10KTCYx wrong? Thank you for your time!


Code:
void User_Autonomous_Code(void)
{
  /* Initialize all PWMs and Relays when entering Autonomous mode, or else it
     will be stuck with the last values mapped from the joysticks.  Remember, 
     even when Disabled it is reading inputs from the Operator Interface. 
  */
  pwm01 = pwm02 = pwm03 = pwm04 = 127;
  pwm05 = pwm06 = pwm07 = pwm08 = 127;
  pwm09 = pwm10 = pwm11 = pwm12 = 127;

  while (autonomous_mode)   /* DO NOT CHANGE! */
  {
    if (statusflag.NEW_SPI_DATA)      /* 18.5ms loop area */
    {
      Getdata(&rxdata);   /* DO NOT DELETE, or you will be stuck here forever! */

     /* Add your own code here. */


pwm02=100;
pwm03=155;

Delay10KTCYx(5000);

pwm02=127;
pwm03=127;



      printf("%2x : %2x %2x %2x %2x %2x %2x\n",(int)rxdata.rc_receiver_status_byte.allbits,
        (int)PWM_in1,(int)PWM_in2,(int)pwm01,(int)pwm02,(int)pwm03,(int)pwm04);

 




  Putdata(&txdata);   /* DO NOT DELETE, or you will get no PWM outputs! */
    }
  }
}
  #2   Spotlight this post!  
Unread 03-08-2010, 22:15
Foster Foster is offline
Engineering Program Management
VRC #8081 (STEMRobotics)
Team Role: Mentor
 
Join Date: Jul 2007
Rookie Year: 2005
Location: Delaware
Posts: 1,393
Foster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond repute
Re: Delay10KTCYx in C18

Your code is in the middle of a loop that NEEDS to get data every 18.5ms and return back a I'm alive message. If you wait for 5 seconds the master CPU is going to think there is a problem and reset the slave.

What you want to do is count the number of times you've been through the loop and when it's been 5 seconds (5 sec / 18.5 ms) then set the PWM values.

autoseconds = autoseconds + 185;

If autoseconds > 5000 then pwm = 127.
__________________
Foster - VEX Delaware - 17 teams -- Chief Roboteer STEMRobotics.org
2010 - Mentor of the Year - VEX Clean Sweep World Championship
2006-2016, a decade of doing VEX, time really flies while having fun
Downingtown Area Robotics Web site and VEXMen Team Site come see what we can do for you.
  #3   Spotlight this post!  
Unread 04-08-2010, 11:50
Mark McLeod's Avatar
Mark McLeod Mark McLeod is offline
Just Itinerant
AKA: Hey dad...Father...MARK
FRC #0358 (Robotic Eagles)
Team Role: Engineer
 
Join Date: Mar 2003
Rookie Year: 2002
Location: Hauppauge, Long Island, NY
Posts: 8,835
Mark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond repute
Re: Delay10KTCYx in C18

You've got lots of options we can help you with. Time can be based on counting the number of loops within the 18.5ms loop area or based on a hardware timer.

You can learn about state machines - what we typically use in cases like these.
Code:
static int counter=0; //keep track of loops to use as a crude timer - static keeps it around from call to call and isn't necessary if you never leave the subroutine.
static int autostate=1;   //keep track of what step we're supposed to be doing
 
  switch (autostate)
  {
    case 1:   // Drive forward
        pwm02 = 100;
        pwm03 = 155;  //motor is reversed
        if (counter>54)  //1 second (1 sec divided by 18.5ms = 54 loops per second)
        {  
           autostate = 2;  // move on to the next step
           counter = 0;    // reset our timer for the next step
        }
 
    case 2:   // Turnaround
        pwm02 = 100;
        pwm03 = 100;  //motor is reversed
        if (counter>108)  //2 seconds
        {  
           autostate = 3;
           counter = 0;
        }
 
    case 3:   // Drive forward (returning now)
        pwm02 = 100;
        pwm03 = 155;  //motor is reversed
        if (counter>54)  //1 second
        {  
           autostate = 4;
           counter = 0;
        }
 
     case 4:   // Stop - What to do when everything else is done
     default:  // also what to do if an invalid autostate occurs
 
       pwm02 = pwm03= 127;   // Make sure the last thing you do is always stop
  }
  counter++;
You can also write your own WAIT subroutine to do what you want if you prefer to flow through one set of commands. There's an easy way to do this for Autonomous based on the User_Autonomous_Code structure and counting the way Foster suggested. It's not something you would use in Teleop where you want to respond to driver commands instantaneously.
__________________
"Rationality is our distinguishing characteristic - it's what sets us apart from the beasts." - Aristotle

Last edited by Mark McLeod : 04-08-2010 at 13:50.
  #4   Spotlight this post!  
Unread 04-08-2010, 15:28
siaohuang siaohuang is offline
Registered User
no team
 
Join Date: Aug 2010
Location: Fort Wayne IN
Posts: 10
siaohuang is an unknown quantity at this point
Re: Delay10KTCYx in C18

I have it to work thank you!!

This is what I did
Code:
static int counter=0;


pwm02=100;
pwm03=155;

counter= ++counter ;

if(counter>271){   (5/18.5ms)
  pwm02=127;
  pwm03=127; 
}
and the robot moved for 5 seconds and it stopped! What I'm doing right here is the way Foster suggested right ? I think the both of you are doing the same thing right? I have a question about the 18.5ms is it true that no matter how long the code, it will always take 18.5ms in the loop?

Also MARK can you show me how to write the Wait subroutine?

I can't thank you guys enough! You've been such great help!

Last edited by siaohuang : 04-08-2010 at 15:32.
  #5   Spotlight this post!  
Unread 04-08-2010, 16:44
Mark McLeod's Avatar
Mark McLeod Mark McLeod is offline
Just Itinerant
AKA: Hey dad...Father...MARK
FRC #0358 (Robotic Eagles)
Team Role: Engineer
 
Join Date: Mar 2003
Rookie Year: 2002
Location: Hauppauge, Long Island, NY
Posts: 8,835
Mark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond repute
Re: Delay10KTCYx in C18

That looks good.
Yes, I was just showing an elaboration on what Foster told you. Instead of the Case statement you can use If statements like you did.

The only way the loop will take longer than 18.5ms is if the code you add takes more than 18.5ms to execute and slows everything down so you don't get to the "if (statusflag.NEW_SPI_DATA)" statement in time. That would take an intense time-consuming internal loop, not the sets and checks you're doing.

For a simple Wait just duplicate the structure you already recognize. You want to repeat all the work that routine does, so the system doesn't lockup while you wait.
I just dashed this off and haven't checked it, but this is the general idea using what you've already learned. You'd add something like this before User_Autonomous_Code.
Code:
void My_Wait(int milliseconds)
{
  int elapsedtime=0;  // in increments of 18.5ms
  int elapsedcount=0;  // in units of 18.5ms
 
  while((elapsedtime < milliseconds) & autonomous_mode)  // also quit if Auto mode happens to end
  {
    if (statusflag.NEW_SPI_DATA)      /* 18.5ms loop area */
    {
      elapsedcount++;
      elapsedtime = elapsedcount * 185 / 10; //the Vex PIC processor doesn't have floating point
      Getdata(&rxdata); // tells us when Auto Mode is over
      Putdata(&txdata); // Lets the master controller know we're alive and well
    }
  }
}
And then in User_Autonomous_Code you can do something like this:
pwm02 = 100;
pwm03 = 155;
My_Wait(5000);
pwm02 = 127;
pwm03 = 127;
__________________
"Rationality is our distinguishing characteristic - it's what sets us apart from the beasts." - Aristotle

Last edited by Mark McLeod : 04-08-2010 at 20:17.
  #6   Spotlight this post!  
Unread 04-08-2010, 22:18
Foster Foster is offline
Engineering Program Management
VRC #8081 (STEMRobotics)
Team Role: Mentor
 
Join Date: Jul 2007
Rookie Year: 2005
Location: Delaware
Posts: 1,393
Foster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond repute
Re: Delay10KTCYx in C18

I had similar code for when I was doing MPLabs. I had a fancy one that would let you have multiple threads and time a few things at the same time.

Ahhhh the days of rolling your own components, the sweet smell of 1's and 0's .

Anyway today the RobotC compiler does all of that for you. It also has tasks that you can spawn off to do specific functions and not wait in the main line.

Marks 'case' code is a good example of how we would put state machines together and have them do the heavy lifting of what the robot code needed to do. A little work with Google will get you some good tutorials on state machines.

But it looks like you are on the right track of getting your robot to move.
__________________
Foster - VEX Delaware - 17 teams -- Chief Roboteer STEMRobotics.org
2010 - Mentor of the Year - VEX Clean Sweep World Championship
2006-2016, a decade of doing VEX, time really flies while having fun
Downingtown Area Robotics Web site and VEXMen Team Site come see what we can do for you.
  #7   Spotlight this post!  
Unread 06-08-2010, 15:47
siaohuang siaohuang is offline
Registered User
no team
 
Join Date: Aug 2010
Location: Fort Wayne IN
Posts: 10
siaohuang is an unknown quantity at this point
Re: Delay10KTCYx in C18

Thank you so much! Mark and Foster ! I seem to get the idea of controlling the timer , but the 18.5 milisecond loop is really an enigma to me, like, how did they come up with the number 18.5ms (in the code that Mark provided me there is also an if loop and it was also stated /* 18.5ms loop area */ how did you know that?)and how will we know that the code that I've written had exceeded 18.5ms

But anyway right now I've moved on, I'm using the sensors! Using Limit Switch Sensors and Bumper Sensors

and here is what I did the first time

Code:
static int counter=0;
static int signal=0;

void User_Autonomous_Code(void)
{
  /* Initialize all PWMs and Relays when entering Autonomous mode, or else it
     will be stuck with the last values mapped from the joysticks.  Remember, 
     even when Disabled it is reading inputs from the Operator Interface. 
  */
  pwm01 = pwm02 = pwm03 = pwm04 = 127;
  pwm05 = pwm06 = pwm07 = pwm08 = 127;
  pwm09 = pwm10 = pwm11 = pwm12 = 127;

  while (autonomous_mode)   /* DO NOT CHANGE! */
  {
    if (statusflag.NEW_SPI_DATA)      /* 18.5ms loop area */
    {
      Getdata(&rxdata);   /* DO NOT DELETE, or you will be stuck here forever! */

     /* Add your own code here. */


pwm02=100;
pwm03=155;

counter= ++counter ;
if(counter>541){   
  pwm02=127;
  pwm03=127; 
}

signal=Get_Analog_Value(rc_ana_in02);

if (signal!=0){
  pwm02=127;
  pwm03=127; 
}


      printf("%2x : %2x %2x %2x %2x %2x %2x\n",(int)rxdata.rc_receiver_status_byte.allbits,
        (int)PWM_in1,(int)PWM_in2,(int)pwm01,(int)pwm02,(int)pwm03,(int)pwm04);

      Putdata(&txdata);   /* DO NOT DELETE, or you will get no PWM outputs! */
    }
  }
}
and here's what happened it was stationed initially, when I press the button the robot moved forward... which I think there is nothing wrong with that but when I tried to do the other way around

Code:
static int counter=0;
static int signal=1;

void User_Autonomous_Code(void)
{
  /* Initialize all PWMs and Relays when entering Autonomous mode, or else it
     will be stuck with the last values mapped from the joysticks.  Remember, 
     even when Disabled it is reading inputs from the Operator Interface. 
  */
  pwm01 = pwm02 = pwm03 = pwm04 = 127;
  pwm05 = pwm06 = pwm07 = pwm08 = 127;
  pwm09 = pwm10 = pwm11 = pwm12 = 127;

  while (autonomous_mode)   /* DO NOT CHANGE! */
  {
    if (statusflag.NEW_SPI_DATA)      /* 18.5ms loop area */
    {
      Getdata(&rxdata);   /* DO NOT DELETE, or you will be stuck here forever! */

     /* Add your own code here. */


pwm02=100;
pwm03=155;

counter= ++counter ;
if(counter>541){   
  pwm02=127;
  pwm03=127; 
}

signal=Get_Analog_Value(rc_ana_in02);

if (signal=0){
  pwm02=127;
  pwm03=127; 
}


      printf("%2x : %2x %2x %2x %2x %2x %2x\n",(int)rxdata.rc_receiver_status_byte.allbits,
        (int)PWM_in1,(int)PWM_in2,(int)pwm01,(int)pwm02,(int)pwm03,(int)pwm04);
 
      Putdata(&txdata);   /* DO NOT DELETE, or you will get no PWM outputs! */
    }
  }
}
and it completely ignored me pressing button. What I was trying to do is let the robot move forward for 10 seconds and during the period of time I want it to stop when I pressed the botton. I understand that when I press the button it will convert the voltage at the connection point to a 10 bit (0 to 1023) value representing that voltage.And when the button is press it will generate a Electrical gound 0 voltage. I assigned a variable of type unsigned int it should be used when reading the value. And somehow it was bypassing the the "if" loop I assigned

I've been growing so dependent on you guys...Thank you so much for your help...

Last edited by siaohuang : 06-08-2010 at 15:49. Reason: the code wrapping didn't come out
  #8   Spotlight this post!  
Unread 06-08-2010, 16:10
Foster Foster is offline
Engineering Program Management
VRC #8081 (STEMRobotics)
Team Role: Mentor
 
Join Date: Jul 2007
Rookie Year: 2005
Location: Delaware
Posts: 1,393
Foster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond reputeFoster has a reputation beyond repute
Re: Delay10KTCYx in C18

The problem is that the buttons go from approximately 0 to ~255 and it's the approximate part that is the issue.

Try:
Code:
if (signal < 20){  
  pwm02=127;
  pwm03=127;
}
The other button would be
Code:
if (signal > 235){
  pwm02=127;  
  pwm03=127; 
}
While it's supposed to be zero, there are analog components in the circuit, and they could be adding just a little resistance to the circuit to make it not be exactly zero. You could print the value of signal out to see what it really is.

The 18.5 ms has to do with how long it takes the control signals from the transmitter to get to the master CPU. The signals from the transmitters are PWM with a fixed length channel. On my wiki there is the following note that I've copied from someone named Tinkerman.

Quote:
The measured separation pulse (high pulse) is a fixed 400usec long. Pushing the stick up shortens the channel's "low" pulse about 400usec.

Pushing the stick down lengthens the pulse about 420usec.

No deflection on the stick gives a 1.12msec low pulse (for a total of 1.52msec from the beginning of the separation pulse.)

Every five counts of channel trim adjusts the pulse length 6usec. Minus trim values shorten the "low" pulse time. The top button (chans. 5 and 6) shortens the "low" pulse time 560usec and the bottom button lengthens the "low" pulse 560usec. Each packet of 6 channels repeats roughly every 18.5msec.
Edited: I found Tinkerman's orginal article and there are links in it that may be useful.

http://www.vexfan.com/viewtopic.php?t=227
__________________
Foster - VEX Delaware - 17 teams -- Chief Roboteer STEMRobotics.org
2010 - Mentor of the Year - VEX Clean Sweep World Championship
2006-2016, a decade of doing VEX, time really flies while having fun
Downingtown Area Robotics Web site and VEXMen Team Site come see what we can do for you.

Last edited by Foster : 06-08-2010 at 16:14. Reason: Add links to the orginal article
  #9   Spotlight this post!  
Unread 06-08-2010, 16:17
Mark McLeod's Avatar
Mark McLeod Mark McLeod is offline
Just Itinerant
AKA: Hey dad...Father...MARK
FRC #0358 (Robotic Eagles)
Team Role: Engineer
 
Join Date: Mar 2003
Rookie Year: 2002
Location: Hauppauge, Long Island, NY
Posts: 8,835
Mark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond repute
Re: Delay10KTCYx in C18

In addition to what Foster covered...

if statement comparisons need double equal signs (==).
A single equal sign doesn't compare, it changes the value.
So
if (signal=0)
changes the value of signal to zero, then evaluates
if(0)
which will always be False.

The correct way is:
if (signal==0) {
The 18.5ms is more of a design choice for how often transmission packets are sent. Through the years FIRST has had some variation in packet rates, for instance, the predecessor of the Vex controller used a packet rate of 17ms, and the larger version used for FRC at that time had a rate of 26.2ms.
Whenever you use something like this as a crude timer you'll have to investigate and determine what transmission rate was used.
__________________
"Rationality is our distinguishing characteristic - it's what sets us apart from the beasts." - Aristotle

Last edited by Mark McLeod : 06-08-2010 at 16:31.
  #10   Spotlight this post!  
Unread 06-08-2010, 17:34
siaohuang siaohuang is offline
Registered User
no team
 
Join Date: Aug 2010
Location: Fort Wayne IN
Posts: 10
siaohuang is an unknown quantity at this point
Re: Delay10KTCYx in C18

Thank you guys so much! I have it working!! After reading I did some adjustments and it worked just as I wanted: When the button is pressed the robot will reverse and make a turn and go straight. Here is my code for that!

Code:
static int counter2=0;
static int counter3=0;
static int signal=1;
static int trigger=0;

pwm02=100;
pwm03=155;

signal=Get_Analog_Value(rc_ana_in02);

if (signal==0){
  trigger=1;
}

if(trigger==1){
   pwm02=155;
   pwm03=100;
counter2=++counter2;   
 if (counter2>109){
         pwm02=155;
         pwm03=155; 
      counter3=++counter3;
      if (counter3>109){
           pwm02=155;
           pwm03=100;
           trigger=0;
           counter2=0;
           counter3=0;
     }	
  }  
}
To Foster I forgot to mention that in the Vex instruction manual says that the buttons are digital sensors, which sends a voltage, but instead of sending a voltage between zero and max, it will send only zero or maximum.And the Signal pin is HIGH when the switch is open, Pushing Switch brings the signalpin voltage to LOW. I wish I can show you guys what I've done, thank you so much, I will move on to the next chapter the light sensors!
Closed Thread


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Trig functions in C18 3.10 dmlawrence Programming 9 08-02-2008 09:33
MPLab 7.20/C18 2.40 Andy L Programming 2 07-04-2007 20:11
C18 v. 2.4 wingnut1705 Programming 2 05-02-2007 15:52
C18 v2.4 CircularLogic FIRST Tech Challenge 2 16-07-2006 15:20
Linux C18 compiler? Servo888 Robotics Education and Curriculum 1 13-12-2003 01:27


All times are GMT -5. The time now is 23:39.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


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