Go to Post Could you explain this concept of a break from FIRST? Did my wife put you up to this? - Gary Dillard [more]
Home
Go Back   Chief Delphi > Technical > Robotics Education and Curriculum
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 09-01-2004, 07:29
squide's Avatar
squide squide is offline
Architeuthis Clarkei
#1056 (Kekoa O Ha'aheo)
Team Role: Mentor
 
Join Date: Dec 2003
Rookie Year: 2004
Location: Hilo, Hawaii
Posts: 44
squide is on a distinguished road
Some EDURobotics Problems

Hey everyone! I'm having a few problems with the EDURobot, and I was hoping I could get a little help here.
  • Input Values - Our analog inputs read in values from about 10-998, and our digital inputs read 0 or 256. I'm not sure if this is that much of a problem. We've been able to work around them when programming. Apparently the analog inputs should be 0-255 and digital inputs 0 or 1. I'm pretty sure I've put the right devices in the right pins .
  • Banner Sensors (QS18VN6LV) - We learned that the first sensor we worked with was bad (after a week or so ), and after getting our second one to work it also went bad. We have a third sensor working, but in summary it's been a pain. After looking through the manuals for the sensors, we learned that the sensors were not working due to an "output overload" (blinking green light). One sensor blinked when it detected dark, the other blinked only when it detected light. How do we circumvent this error?

Thanks!

The attached pictures are of the EDURobot on 01/09, 01/08, and 01/05.
Attached Thumbnails
Click image for larger version

Name:	edubot010504.jpg
Views:	78
Size:	66.3 KB
ID:	1666  Click image for larger version

Name:	edubot010804.jpg
Views:	57
Size:	92.0 KB
ID:	1667  Click image for larger version

Name:	edubot010904.jpg
Views:	79
Size:	98.6 KB
ID:	1668  

Last edited by squide : 09-01-2004 at 16:05.
  #2   Spotlight this post!  
Unread 09-01-2004, 07:48
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,830
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: Some EDURobotics Problems

Quote:
Originally Posted by squide
Hey everyone! I'm having a few problems with the EDURobot, and I was hoping I could get a little help here.
[list][*]Input Values - Our analog inputs read in values from about 10-998, and our digital inputs read 0 or 256. I'm not sure if this is that much of a problem. We've been able to work around them when programming. Apparently the analog inputs should be 0-255 and digital inputs 0 or 1. I'm pretty sure I've put the right devices in the right pins .
.
The analog inputs are 10 bits with values from 0-1023.
The digital inputs are 0 & 1

Are you sure you defined the input pins as analog or digital correctly?
The default EDU code for instance defines inputs 1 & 2 as analog inputs and the rest as either digital inputs or outputs. Check in user_routines.c
__________________
"Rationality is our distinguishing characteristic - it's what sets us apart from the beasts." - Aristotle
  #3   Spotlight this post!  
Unread 09-01-2004, 08:23
squide's Avatar
squide squide is offline
Architeuthis Clarkei
#1056 (Kekoa O Ha'aheo)
Team Role: Mentor
 
Join Date: Dec 2003
Rookie Year: 2004
Location: Hilo, Hawaii
Posts: 44
squide is on a distinguished road
Re: Some EDURobotics Problems

Quote:
Originally Posted by Mark McLeod
Are you sure you defined the input pins as analog or digital correctly? The default EDU code for instance defines inputs 1 & 2 as analog inputs and the rest as either digital inputs or outputs. Check in user_routines.c
Thanks for the reply!

We're using an optical sensor to test for input without modifying the Default Code besides the printf statement. We put the sensor in Pin 6 (rc_dig_in06), so with the default configurations it should be okay. It also behaved the same in 8 & 10.
  #4   Spotlight this post!  
Unread 09-01-2004, 11:06
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,830
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: Some EDURobotics Problems

Quote:
Originally Posted by squide
Thanks for the reply!

We're using an optical sensor to test for input without modifying the Default Code besides the printf statement. We put the sensor in Pin 6 (rc_dig_in06), so with the default configurations it should be okay. It also behaved the same in 8 & 10.

Lets try this tack then just to make sure it isn't a printf issue.
What does your printf look like and how are the variables you use in it declared? Just to make sure you are seeing the correct values.
The printf implementation will give you bad results that look right if you treat it as a normal C printf.
e.g.,

unsigned char digitalvalue;
unsigned int analogvalue;

digitalvalue = (unsigned char) rc_dig_in06;
analogvalue = (unsigned int) Get_Analog_Value(rc_ana_in01);

printf("My digital value %d, My analog value %d", (int) digitalvalue, (int)analogvalue);

We wrote our own print functions to get what we want, especially since printf takes up so much space. You can get the same functionality in 40 bytes rather than the 4000 or so printf takes up.
__________________
"Rationality is our distinguishing characteristic - it's what sets us apart from the beasts." - Aristotle

Last edited by Mark McLeod : 09-01-2004 at 11:10.
  #5   Spotlight this post!  
Unread 09-01-2004, 16:59
squide's Avatar
squide squide is offline
Architeuthis Clarkei
#1056 (Kekoa O Ha'aheo)
Team Role: Mentor
 
Join Date: Dec 2003
Rookie Year: 2004
Location: Hilo, Hawaii
Posts: 44
squide is on a distinguished road
Re: Some EDURobotics Problems

Quote:
Originally Posted by Mark McLeod
unsigned char digitalvalue;
unsigned int analogvalue;

digitalvalue = (unsigned char) rc_dig_in06;
analogvalue = (unsigned int) Get_Analog_Value(rc_ana_in01);

printf("My digital value %d, My analog value %d", (int) digitalvalue, (int)analogvalue);
Thanks, that did the trick. I'll remember to do something like that for printf's. Here were my statements before:

printf("Analog 1 = %d\n", Get_Analog_Value(rc_ana_in01));
printf("Digital 6 = %d\n", rc_dig_in06);

So now I can see why it didn't work!
  #6   Spotlight this post!  
Unread 17-01-2004, 21:00
ealex292 ealex292 is offline
Registered User
#0751
Team Role: Programmer
 
Join Date: Jan 2004
Location: Woodside Priory
Posts: 2
ealex292 is an unknown quantity at this point
Send a message via AIM to ealex292
Angry Touch Sensors

I've been trying to add the touch sensors from a few years ago (presumably) to my team's edu bot, but whenever I press in the sensor, the robot either turns off entirely or nothing happens at all. It turns off entirely when I plug it into the +5V and BLK (I've tried Digital I/O 1,2,5,6, and 15, and interupts 1,2, and 4), and nothing happens with +5V and SIG.

The code is the default for all other files, and for user_routines.c it is:

/************************************************** *****************************
* FILE NAME: user_routines.c <EDU VERSION>
*
* DESCRIPTION:
* This file contains the default mappings of inputs
* (like switches, joysticks, and buttons) to outputs on the EDU RC.
*
* USAGE:
* You can either modify this file to fit your needs, or remove it from your
* project and replace it with a modified copy.
*
************************************************** *****************************/

#include "ifi_aliases.h"
#include "ifi_default.h"
#include "ifi_utilities.h"
#include "user_routines.h"
#include "printf_lib.h"


/*** DEFINE USER VARIABLES AND INITIALIZE THEM HERE ***/
/* EXAMPLES: (see MPLAB C18 User's Guide, p.9 for all types)
unsigned char wheel_revolutions = 0; (can vary from 0 to 255)
unsigned int delay_count = 7; (can vary from 0 to 65,535)
int angle_deviation = 142; (can vary from -32,768 to 32,767)
unsigned long very_big_counter = 0; (can vary from 0 to 4,294,967,295)
*/

//Alex's additions

//Constants
//Motors
#define LEFT_MOT pwm04
#define RIGHT_MOT pwm03

//Motor Speeds

//Sensors

//Other

//Variables


/************************************************** *****************************
* FUNCTION NAME: Limit_Switch_Max
* PURPOSE: Sets a PWM value to neutral (127) if it exceeds 127 and the
* limit switch is on.
* CALLED FROM: this file
* ARGUMENTS:
* Argument Type IO Description
* -------- ------------- -- -----------
* switch_state unsigned char I limit switch state
* *input_value pointer O points to PWM byte value to be limited
* RETURNS: void
************************************************** *****************************/
void Limit_Switch_Max(unsigned char switch_state, unsigned char *input_value)
{
if (switch_state == CLOSED)
{
if(*input_value > 127)
*input_value = 127;
}
}


/************************************************** *****************************
* FUNCTION NAME: Limit_Switch_Min
* PURPOSE: Sets a PWM value to neutral (127) if it's less than 127 and the
* limit switch is on.
* CALLED FROM: this file
* ARGUMENTS:
* Argument Type IO Description
* -------- ------------- -- -----------
* switch_state unsigned char I limit switch state
* *input_value pointer O points to PWM byte value to be limited
* RETURNS: void
************************************************** *****************************/
void Limit_Switch_Min(unsigned char switch_state, unsigned char *input_value)
{
if (switch_state == CLOSED)
{
if(*input_value < 127)
*input_value = 127;
}
}


/************************************************** *****************************
* FUNCTION NAME: Limit_Mix
* PURPOSE: Limits the mixed value for one joystick drive.
* CALLED FROM: Default_Routine, this file
* ARGUMENTS:
* Argument Type IO Description
* -------- ---- -- -----------
* intermediate_value int I
* RETURNS: unsigned char
************************************************** *****************************/
unsigned char Limit_Mix (int intermediate_value)
{
static int limited_value;

if (intermediate_value < 2000)
{
limited_value = 2000;
}
else if (intermediate_value > 2254)
{
limited_value = 2254;
}
else
{
limited_value = intermediate_value;
}
return (unsigned char) (limited_value - 2000);
}


/************************************************** *****************************
* FUNCTION NAME: Setup_Who_Controls_Pwms
* PURPOSE: Each parameter specifies what processor will control the pwm.
*
* CALLED FROM: User_Initialization
* Argument Type IO Description
* -------- ---- -- -----------
* pwmSpec1 int I USER/MASTER (defined in ifi_aliases.h)
* pwmSpec2 int I USER/MASTER
* pwmSpec3 int I USER/MASTER
* pwmSpec4 int I USER/MASTER
* pwmSpec5 int I USER/MASTER
* pwmSpec6 int I USER/MASTER
* pwmSpec7 int I USER/MASTER
* pwmSpec8 int I USER/MASTER
* RETURNS: void
************************************************** *****************************/
static void Setup_Who_Controls_Pwms(int pwmSpec1,int pwmSpec2,int pwmSpec3,int pwmSpec4,
int pwmSpec5,int pwmSpec6,int pwmSpec7,int pwmSpec8)
{
txdata.pwm_mask = 0xFF; /* Default to master controlling all PWMs. */
if (pwmSpec1 == USER) /* If User controls PWM1 then clear bit0. */
txdata.pwm_mask &= 0xFE; /* same as txdata.pwm_mask = txdata.pwm_mask & 0xFE; */
if (pwmSpec2 == USER) /* If User controls PWM2 then clear bit1. */
txdata.pwm_mask &= 0xFD;
if (pwmSpec3 == USER) /* If User controls PWM3 then clear bit2. */
txdata.pwm_mask &= 0xFB;
if (pwmSpec4 == USER) /* If User controls PWM4 then clear bit3. */
txdata.pwm_mask &= 0xF7;
if (pwmSpec5 == USER) /* If User controls PWM5 then clear bit4. */
txdata.pwm_mask &= 0xEF;
if (pwmSpec6 == USER) /* If User controls PWM6 then clear bit5. */
txdata.pwm_mask &= 0xDF;
if (pwmSpec7 == USER) /* If User controls PWM7 then clear bit6. */
txdata.pwm_mask &= 0xBF;
if (pwmSpec8 == USER) /* If User controls PWM8 then clear bit7. */
txdata.pwm_mask &= 0x7F;
}


/************************************************** *****************************
* FUNCTION NAME: User_Initialization
* PURPOSE: This routine is called first (and only once) in the Main function.
* You may modify and add to this function.
* The primary purpose is to set up the DIGITAL IN/OUT - ANALOG IN
* pins as analog inputs, digital inputs, and digital outputs.
* CALLED FROM: main.c
* ARGUMENTS: none
* RETURNS: void
************************************************** *****************************/
void User_Initialization (void)
{
rom const char *strptr = "IFI User Processor Initialized ...";

/* FIRST: Set up the pins you want to use as analog INPUTs. */
IO1 = IO2 = INPUT; /* Used for analog inputs. */
/*
Note: IO1 = IO2 = IO3 = IO4 = INPUT;
is the same as the following:

IO1 = INPUT;
IO2 = INPUT;
IO3 = INPUT;
IO4 = INPUT;
*/

/* SECOND: Configure the number of analog channels. */
Set_Number_of_Analog_Channels(TWO_ANALOG); /* See ifi_aliases.h */

/* THIRD: Set up any extra digital inputs. */
/* The six INTERRUPTS are already digital inputs. */
/* If you need more then set them up here. */
/* IOxx = IOyy = INPUT; */
IO6 = IO8 = IO10 = INPUT; /* Used for limit switch inputs. */
IO12 = IO14 = IO16 = INPUT; /* Used for limit switch inputs. */

/* FOURTH: Set up the pins you want to use as digital OUTPUTs. */
IO3 = IO4 = OUTPUT;
IO5 = IO7 = IO9 = OUTPUT; /* For connecting to adjacent limit switches. */
IO11 = IO13 = IO15 = OUTPUT; /* For connecting to adjacent limit switches. */

/* FIFTH: Initialize the values on the digital outputs. */
rc_dig_out03 = rc_dig_out04 = 0;
rc_dig_out05 = rc_dig_out07 = rc_dig_out09 = 0;
rc_dig_out11 = rc_dig_out13 = rc_dig_out15 = 0;

/* SIXTH: Set your initial PWM values. Neutral is 127. */
pwm01 = pwm02 = pwm03 = pwm04 = pwm05 = pwm06 = pwm07 = pwm08 = 127;

/* SEVENTH: Choose which processor will control which PWM outputs. */
Setup_Who_Controls_Pwms(MASTER,MASTER,MASTER,MASTE R,MASTER,MASTER,MASTER,MASTER);

/* EIGHTH: Set your PWM output type. Only applies if USER controls PWM 1, 2, 3, or 4. */
/* Choose from these parameters for PWM 1-4 respectively: */
/* IFI_PWM - Standard IFI PWM output generated with Generate_Pwms(...) */
/* USER_CCP - User can use PWM pin as digital I/O or CCP pin. */
Setup_PWM_Output_Type(IFI_PWM,IFI_PWM,IFI_PWM,IFI_ PWM);

/*
Example: The following would generate a 40KHz PWM with a 50% duty cycle
on the CCP2 pin (PWM OUT 1):
CCP2CON = 0x3C;
PR2 = 0xF9;
CCPR2L = 0x7F;
T2CON = 0;
T2CONbits.TMR2ON = 1;
Setup_PWM_Output_Type(USER_CCP,IFI_PWM,IFI_PWM,IFI _PWM);
*/

/* Add any other user initialization code here. */

Initialize_Serial_Comms();

Putdata(&txdata); /* DO NOT CHANGE! */

printf("%s\n", strptr); /* Optional - Print initialization message. */

User_Proc_Is_Ready(); /* DO NOT CHANGE! - last line of User_Initialization */
}


/************************************************** *****************************
* FUNCTION NAME: Process_Data_From_Master_uP
* PURPOSE: Executes every 17ms when it gets new data from the master
* microprocessor.
* CALLED FROM: main.c
* ARGUMENTS: none
* RETURNS: void
************************************************** *****************************/
void Process_Data_From_Master_uP(void)
{
Getdata(&rxdata); /* Get fresh data from the master microprocessor. */

Default_Routine(); /* Optional. See below. */

/* Add your own code here. */

printf("PWM OUT 7 = %d, PWM OUT 8 = %d\n",(int)pwm07,(int)pwm08); /* printf EXAMPLE */

Putdata(&txdata); /* DO NOT CHANGE! */
}


/************************************************** *****************************
* FUNCTION NAME: Default_Routine
* PURPOSE: Performs the default mappings of inputs to outputs for the
* Robot Controller.
* CALLED FROM: this file, Process_Data_From_Master_uP routine
* ARGUMENTS: none
* RETURNS: void
************************************************** *****************************/
void Default_Routine(void)
{
LEFT_MOT = RIGHT_MOT = 255;
} /* END Default_Routine(); */


/************************************************** ****************************/
/************************************************** ****************************/
/************************************************** ****************************/

(I originally discovered this with the on/off touch sensor tutorial (code at http://www.rec.ri.cmu.edu/education/...uch/index.htm#), which is why I had a touch sensor plugged in.)

Anyway, I'd welcome some help.
  #7   Spotlight this post!  
Unread 17-01-2004, 21:28
Pat Fairbank's Avatar
Pat Fairbank Pat Fairbank is offline
Circuit Breaker
FRC #0254 (The Cheesy Poofs)
Team Role: Engineer
 
Join Date: Mar 2003
Rookie Year: 2001
Location: San Jose, CA
Posts: 2,132
Pat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond repute
Send a message via MSN to Pat Fairbank
Re: Some EDURobotics Problems

I believe you're supposed to connect switches to BLK and SIG, the top and bottom pins. The EDU controller has a built in circuit breaker that shuts off power when you connect a switch between +5V and BLK, since it can fry the circuits. Since you didn't say that you tried attaching the switch to SIG and BLK, I would guess that that is your problem.
__________________
Patrick Fairbank
Team 254 | Mentor (2012-)
Team 1503 | Mentor (2007-2011)
Team 296 | Alumnus (2001-2004) | Mentor (2005-2006)

patfairbank.com
  #8   Spotlight this post!  
Unread 18-01-2004, 01:35
ealex292 ealex292 is offline
Registered User
#0751
Team Role: Programmer
 
Join Date: Jan 2004
Location: Woodside Priory
Posts: 2
ealex292 is an unknown quantity at this point
Send a message via AIM to ealex292
Re: Some EDURobotics Problems

Quote:
Originally Posted by Pat Fairbank
I believe you're supposed to connect switches to BLK and SIG, the top and bottom pins. The EDU controller has a built in circuit breaker that shuts off power when you connect a switch between +5V and BLK, since it can fry the circuits. Since you didn't say that you tried attaching the switch to SIG and BLK, I would guess that that is your problem.
How would I go about doing that, since SIG and BLK aren't next to each other? Should I get some wire and try to connect them that way?
  #9   Spotlight this post!  
Unread 18-01-2004, 10:12
Pat Fairbank's Avatar
Pat Fairbank Pat Fairbank is offline
Circuit Breaker
FRC #0254 (The Cheesy Poofs)
Team Role: Engineer
 
Join Date: Mar 2003
Rookie Year: 2001
Location: San Jose, CA
Posts: 2,132
Pat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond reputePat Fairbank has a reputation beyond repute
Send a message via MSN to Pat Fairbank
Re: Some EDURobotics Problems

I would take a PWM cable, cut off the end with the pins, pull apart the wires, get rid of the middle wire, and then attach the switch to the two wires that are left.
__________________
Patrick Fairbank
Team 254 | Mentor (2012-)
Team 1503 | Mentor (2007-2011)
Team 296 | Alumnus (2001-2004) | Mentor (2005-2006)

patfairbank.com
  #10   Spotlight this post!  
Unread 20-01-2004, 10:27
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,830
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: Some EDURobotics Problems

Quote:
Originally Posted by ealex292
How would I go about doing that, since SIG and BLK aren't next to each other? Should I get some wire and try to connect them that way?
There is an easier way if you have two wire connectors to the limit switches.
The default EDU code sets up several Digital I/O pins as inputs and adjacent ones as outputs. This is so you can use adjacent signal pins for your limit switches. You can change these definitions in user_routines.c in the User_Initialization function.

Code:
  IO6 = IO8 = IO10 = INPUT;      /* Used for limit switch inputs. */
  IO12 = IO14 = IO16 = INPUT;    /* Used for limit switch inputs. */

/* FOURTH: Set up the pins you want to use as digital OUTPUTs. */
  IO3 = IO4 = OUTPUT;
  IO5 = IO7 = IO9 = OUTPUT;     /* For connecting to adjacent limit switches. */
  IO11 = IO13 = IO15 = OUTPUT;  /* For connecting to adjacent limit switches. */
For example, this allows you to connect your limit switch to the two signal pins on Digital I/O 6 and 5. Then you test rc_dig_out06 in your code for an open or closed switch.
__________________
"Rationality is our distinguishing characteristic - it's what sets us apart from the beasts." - Aristotle
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
Do you all have problems with.... Munkaboo Website Design/Showcase 19 03-03-2003 19:51
EduRobotics problems Ian Mackenzie Robotics Education and Curriculum 22 14-12-2002 11:33
EduRobotics and Innovation FIRST system Dave... Robotics Education and Curriculum 13 03-11-2002 19:35
Joystick problems archiver 2001 3 24-06-2002 02:40
Radio problems -- not archiver 2000 1 23-06-2002 22:23


All times are GMT -5. The time now is 05:34.

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