Thread: Help reading pseudo code for car robot

  1. #1
    Registered User
    Join Date
    Sep 2014
    Posts
    2

    Help reading pseudo code for car robot

    I'm doing a practice problem where I need to read pseudo code and understand what it does. I know some of it, but can someone read my logic for the pieces of code and tell me if they're correct?




    For this code, I believe it will move the robot forward while i<650, so it moves it forward for 650 steps in total. Then it sets the motors to 0 when it's finished.
    Code:
    while(i<650)
    { rotateCW(2);    
    rotateCCW(1);    
    Delay1KTCYx(50);
    i++;
    LATD=0x00;     //Set all Port D to 0
    }

    This code I'm having the most trouble with. So while(1) the pot(potentiometer) read's the ADC. Then it scales the adc, not 100% sure what the +20 and *.22 mean, I think it has to do with binary conversions?

    Now it sets pin 1 of port 1 to 0, delays based on pot above, and sets it back to 1, and delays again. I'm confused what this function is actually doing, I assume something to do with controlling motor speed based on the potentiometer.
    Code:
    void main(void){TRISD = 0x00;         // Setting port D to outputs
    LATDbits.LATD0 = 1;       // Setting bit 0 of port D to 1
    while(1)
    {              
    pot = readADC();
    pot = pot * 0.2297 + 20;
        LATDbits.LATD1 = 0;    
        Delay10KTCYx(pot);      
        LATDbits.LATD1 = 1;      
        Delay10KTCYx(pot);      
    }
    return;
    }

    My best guess is: The car moves forward 400 steps, stop, turn right for 230 steps, stop. At this point it would begin moving straight, and it would turn left/right as needed to keep the robot in the center of the track.

    Code:
    void main(void)
    {
    for(i=0;i<400;i++)
    {   
    rotateCW(2,motor);    //Rotate motor two (one step)
    rotateCCW(1,motor);    //Rotate motor one (one step)
    Delay1KTCYx(50);
    i++;
    LATD=0x00;     //Set all Port D to 0
    }
    i=0;
    while(i < 230)
    {
    rotateCW(2); // Rotate motor two by one step
    rotateCW(1); // Rotate motor by one step
    Delay1KTCYx(50);    // Changing the argument in the delay function will change the speed at which        
                                         // the motor rotates. Delay equals 1000 x 50 x 1/12 = 4.167 ms
    i++;
    LATD = 0x00;    
    }
    i=0;
    for (i=0;i<400;i++)
    {   
    SetChanADC (ADC_CH0);    
    ConvertADC();      
    while (BusyADC());    
    leftsensor = ReadADC();    If (leftsensor>400)
    {
    TurnRight(5);
    GoForwardx(1);
    }
    If (leftsensor<300)
    {
    TurnLeft(5);
    GoForwardx(5);
    }
    If (leftsensor<400)&&(leftsensor>300)
    {
    GoForwardx(5);
    i++;
    }
    }
    Last edited by connectrme; 09-12-2014 at 02:39 PM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    The first thing it needs is indentation.
    Indent style - Wikipedia, the free encyclopedia

    > rotateCW(2,motor); //Rotate motor two (one step)
    > rotateCCW(1,motor); //Rotate motor one (one step)
    Do you know what CW and CCW mean?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    First one - if "LATD=0x00;" is what turns the motors off, you want that to happen outside the loop (i.e. after the loop completes).

    Code:
    while( /* condition */ )
    {
        /* stuff that gets looped */
    }
    
    /* stuff that happens after the loop */
    I don't know what the "rotate" functions are supposed to be doing, exactly, but it seems odd you're calling "rotateCW()" (presumably "rotate clockwise") and "rotateCCW()" (presumably "rotate counter-clockwise") when you're only supposed to be moving in a single direction.

    Also note that "for()" loops are better suited for these kind of loops, where a control variable is updated consistently each iteration of the loop (though a "while()" loop is also perfectly acceptable).



    For the second code, it appears you're pretty close.

    ...not 100% sure what the +20 and *.22 mean, I think it has to do with binary conversions?
    Not binary conversions. Since the "pot" value is sent to delay functions, I'd guess adjusting the pot changes the delay value. However, since the ADC reading is presumably not 1:1 with the desired delay values, that reading is modified (perhaps arbitrarily, based on measurements - I can't say based solely on the supplied code).

    Now it sets pin 1 of port 1 to 0, delays based on pot above, and sets it back to 1, and delays again.
    I'm confused what this function is actually doing...
    "High-Delay-Low-Delay" in a loop - that would just create a pulse sequence (the pulse width adjustable based on the delays, as you guessed). As to what this controls - again, it's difficult to say based only on the code alone.



    The third one is difficult to read due to the lack of indentation, in addition to only guessing what the custom functions are supposed to be doing.

    I definitely see some syntax errors in there (If with a capital 'I', not enough parenthesis around the last "if" argument).

    Also, if clearing "LATD" stops the motors after the first loop, they aren't started again before the next loop.

  4. #4
    Registered User
    Join Date
    Sep 2014
    Posts
    2
    The rotateCW and rotateCCW rotate the motor clockwise and counterclockwise, I believe they are in opposite direction going forward since both motors are on opposite sides of the car.

    The LATD function is meant to "clear" port D, where the motors are plugged in. I don't know if it stops the motor, I'm guessing not since it's inside the for loop. Here's the reference I was learning it from:

    Registers
    The microcontroller is completely controlled with registers. To define outputs, a
    register has to be used, but also when using AD converters. Normally, registers are 8
    bit. All the registers used in MPLAB MCC18 have exact the same name as the name
    stated in the datasheet. Registers can be set in different ways, some examples for the register PORTB will follow. PORTB is used for writing to and reading from pins on
    port B (take a look in the datasheet and find out yourself!). Writing a 1 to one of the
    bits of PORTB results in a high voltage on the corresponding output pin. A 0 will
    result in a low voltage. The MSB (most significant bit, the most left one) is used for
    pin B7, the LSB for pin B0.
    PORTB = 0b11111111; //All pins of port B are made high
    PORTB = 255; //All pins of port B are made high
    PORTB = 0xFF; //All pins of port B are made high
    PORTB = 0b10101010; //Pin B7 on, B6 off, B5 on, B4 off, etc.
    PORTB = 170; //Pin B7 on, B6 off, B5 on, B4 off, etc.
    PORTB = 0xAA; //Pin B7 on, B6 off, B5 on, B4 off, etc.

    Here is an example code with some of the functions implemented:

    Code:
    /** I N C L U D E S **********************************************************/
    #include <p18f4550.h>															// PIC Controller header file
    #include <adc.h>																// ADC library functions
    #include <xlcd.h>																// LCD library functions
    #include <delays.h>																// Delay library functions
    #include <stdio.h>																// Standard IO functions
    #include <stdlib.h>																// Standard library functions
    
    
    /** V A R I A B L E S ********************************************************/
    #pragma idata
    
    int stepMotor1 = 4;																// Array index for motor 1.
    int stepMotor2 = 4;																// Array index for motor 2.
    
    char motor[8] = {0b10101010,													// An array of characters which contains the output sequence for the motors
                   	0b10001000,
                   	0b10011001,
                   	0b00010001,
    				0b01010101,
    				0b01000100,
    				0b01100110,
    				0b00100010};
    
    
    /** P R I V A T E  P R O T O T Y P E S ***************************************/
    
    void rotateCW(int motorNum);										// Function for rotating a motor one step in the clockwise direction
    void rotateCCW(int motorNum);										// Function for rotating a motor one step in the counterclockwise direction
    int  readFrontSensor(void);											// Function to read the front sensor
    void goForward(void);												// Function to go forward by 1 step
    void turnRight(int stepNum);                                               // Function to turn right
    
    
    /**V E C T O R  R E M A P P I N G*********************************************/
    
    extern void _startup (void);
    #pragma code _RESET_INTERRUPT_VECTOR = 0x000800
    void  _reset (void){
    	_asm goto _startup _endasm
    }
    
    #pragma code _HIGH_INTERRUPT_VECTOR = 0x000808
    void _high_ISR (void){
    	;
    }
    
    #pragma code _LOW_INTERRUPT_VECTOR = 0x000818
    void _low_ISR (void){
    	;
    }
    
    #pragma code
    
    /** D E C L A R A T I O N S **************************************************/
    
    
    /** U S E R  A P I ***********************************************************/
    
    /******************************************************************************
     * Function:        main
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        main entry point 
     * Note:            None
     *****************************************************************************/
    
    void main(void){
    	
    	int frontSensor = 0;																										// Variable to store front sensor value
    
    	OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_12_TAD, ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS, 12);		// Configure the analog to digital conversion
    	
    	// control loop
    
    	while(1){
    		
    		frontSensor = readFrontSensor();
    
    		if (frontSensor < 250){																									// if the sensor sees nothing in font
    			goForward();
    		}
    		else{
    			turnRight(100);																										// turn right by making 100 steps in each motor
    		}
    	}
    	return;
    }
    
    
    
    /******************************************************************************
     * Function:        readFrontSensor
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          value read from front sensor, 10 bits
     *
     * Side Effects:    None
     *
     * Overview:        This function reads the front sensor which is hooked up with
     *					channel 0 of the ADC of the PIC
     *
     * Note:            None
     *****************************************************************************/
    
    
    int readFrontSensor(void){
    
    	SetChanADC(ADC_CH0);																									// Set the analog input to A0
    	ConvertADC();																											// Start the conversion
    	while(BusyADC());																										// Wait until the conversion is finished
    	return ReadADC();																								        // Store the value from the conversion 
    } 
    
    
    /******************************************************************************
     * Function:        goForward
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function moves the robot 1 step forward 
     *
     * Note:            None
     *****************************************************************************/
    
    
    void goForward(void){
    
    	rotateCCW(2);																								// Rotate motor two step
    	rotateCW(1);    																							// Rotate motor one step
    	
    	Delay1KTCYx(50);																							// Changing the argument in the delay function will change the speed at which the motor rotates. Delay equals 1000 x 50 x 1/12 = 4.167 ms
    	LATD = 0x00;																				                // Set all port D to 0	
    }
    
    /******************************************************************************
     * Function:        turnRight
     *
     * PreCondition:    None
     *
     * Input:           stepNum: Number of steps to make for turning right
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function make the robot to turn right by making certain
     *					number of steps which is indicated by the input
     *
     * Note:            None
     *****************************************************************************/
    
    void turnRight(int stepNum){
    	
    	int i = 0;
    
    	while(i<stepNum){
    		rotateCW(2);																							// Rotate motor two step
    		rotateCW(1);																							// Rotate motor one step
    		Delay1KTCYx(50);																						// Changing the argument in the delay function will change the speed at which the motor rotates. Delay equals 1000 x 50 x 1/12 = 4.167 ms
    		i++;
    		LATD = 0x00;																							// Set all port D to 0	
    	}
    
    	return;
    }
    
    
    /******************************************************************************
     * Function:        rotateCW
     *
     * PreCondition:    None
     *
     * Input:           motorNum - determines which motor, 
     *					motor[] - an array which contains output sequence for the motors
     *
     * Output:          sequence for correct motor operation 
     *
     * Side Effects:    None
     *
     * Overview:        This function rotates the motor one step
     *
     * Note:            None
     *****************************************************************************/
    
    void rotateCW(int motorNum){				
    	if(motorNum==1){
    		stepMotor1 = ++stepMotor1;												// Increment the array index for motor 1
    		if(stepMotor1>7)														// If the array index is out of range the reset it to 0	
    			stepMotor1=0;
    		TRISD &= 0x0f;															// Set the upper 4 bits of port D as outputs
            LATD |= ((motor[stepMotor1]<<4)&0xf0);									// Output the motor step sequence to the upper 4 bits of port D
    	}else{
    		stepMotor2 = ++stepMotor2;												// Increment the array index for motor 2
    		if(stepMotor2>7)														// If the array index is out of range the reset it to 0
    			stepMotor2=0;							
    		TRISD &= 0xf0;															// Set the lower 4 bits of port D as outputs
            LATD |= ((motor[stepMotor2]>>4)&0x0f);									// Output the motor step sequence to the lower 4 bits of port D
    	}
    }
    
    /******************************************************************************
     * Function:        rotateCCW
     *
     * PreCondition:    None
     *
     * Input:           motorNum - determines which motor, 
     *					motor[] - an array which contains output sequence for the motors
     *
     * Output:          sequence for correct motor operation 
     *
     * Side Effects:    None
     *
     * Overview:        This function rotates the motor one step
     *
     * Note:            None
     *****************************************************************************/
    
    void rotateCCW(int motorNum){										
    	if(motorNum==1){															
    		stepMotor1--;															// Decrement the array index for motor 1
    		if(stepMotor1<0)														// If the array index is out of range the reset it to 7														
    			stepMotor1=7;														
    		TRISD &= 0x0f;															// Set the upper 4 bits of port D as outputs
            LATD |= ((motor[stepMotor1]<<4)&0xf0);									// Output the motor step sequence to the upper 4 bits of port D
    	}else{
    		stepMotor2--;															// Decrement the array index for motor 2
    		if(stepMotor2<0)														// If the array index is out of range the reset it to 7
    			stepMotor2=7;
    		TRISD &= 0xf0;															// Set the lower 4 bits of port D as outputs
            LATD |= ((motor[stepMotor2]>>4)&0x0f);									// Output the motor step sequence to the lower 4 bits of port D
    	}
    }

  5. #5
    Registered User
    Join Date
    Nov 2011
    Posts
    161
    Now it sets pin 1 of port 1 to 0, delays based on pot above, and sets it back to 1, and delays again. I'm confused what this function is actually doing, I assume something to do with controlling motor speed based on the potentiometer.

    Code:
    void main(void){TRISD = 0x00;         // Setting port D to outputs
    LATDbits.LATD0 = 1;       // Setting bit 0 of port D to 1
    while(1)
    {              
    pot = readADC();
    pot = pot * 0.2297 + 20;
        LATDbits.LATD1 = 0;    
        Delay10KTCYx(pot);      
        LATDbits.LATD1 = 1;      
        Delay10KTCYx(pot);      
    }
    return;
    }
    Matticus is right in it is basically a high/low pulse generator, scaled as it is for whatever reason (specs of motor).
    Not sure what it does just by the code either, but it is stretching the pulse out and in based on the potentiometer, but still a 50% duty cycle. If it were a speed control for the motors, I would suspect it should be a PWM (pulse width modulation) so for that to work with that code, it should be
    Code:
        LATDbits.LATD1 = 0;
        Delay10KTCYx(TotalPulse - pot);
        LATDbits.LATD1 = 1;
        Delay10KTCYx(pot);
    With 'TotalPulse' being the total cycle and 'pot' changing the 'on' time.
    Then you would be increasing or decreasing the average voltage to the motor.

  6. #6
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Quote Originally Posted by connectrme
    The rotateCW and rotateCCW rotate the motor clockwise and counterclockwise, I believe they are in opposite direction going forward since both motors are on opposite sides of the car.
    I would agree with you there. Assuming we were riding on top of the robot, motor #1 would be on the right and motor #2 would be on the left, since "forward" has motor #1 turning clockwise and motor #2 turning counter-clockwise.

    Quote Originally Posted by connectrme
    The LATD function is meant to "clear" port D, where the motors are plugged in. I don't know if it stops the motor, I'm guessing not since it's inside the for loop.
    I assume, based on the code you posted (and the decent variable names), that PORTD controls a stepper motor (or two actually, one nibble for each wheel). But the code is a bit strange.

    Based on a hasty analysis, it seems that the rotation functions move a wheel one "step" each time they're called. They use a look-up table (the "motor" array) each time to look up the current position of the motor and where to move for the next step (keeping track of the indices with the "stepMotor1" and "stepMotor2" variables). This LUT combines data for each nibble, and the appropriate one is masked during each rotation.

    But after each unit of rotation, it seems the stepper motor is reset back to zero through PORTD in the loops of the "goForward()" and "turnRight()" functions. This would seem to indicate that, instead of the wheels being firmly affixed to the shaft of each stepper motor, it instead "locks" going forward and the shaft is free to spin back after each step without the wheels moving backwards. (I don't know, I don't care to dig that deeply into it.) It also seems that while one motor is moving, the other is "disabled" by setting those other port pins as inputs (the "TRISD" bits).



    So what is your actual goal here? You say you have to analyze pseudocode, but instead offer actual code.

    And it's MCU code to boot, meaning additional difficulties since you have to reason about the hardware as well.

    Tell us clearly what you're after, so we can help you more.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pseudo Code
    By BretFlorida in forum C Programming
    Replies: 2
    Last Post: 04-15-2013, 03:13 PM
  2. robot code
    By pureflip428 in forum C Programming
    Replies: 2
    Last Post: 12-03-2012, 08:28 PM
  3. Writing to/Reading from Pseudo Terminals
    By davo666 in forum C Programming
    Replies: 2
    Last Post: 01-21-2009, 11:10 PM
  4. Pseudo TTY not reading singal character
    By MrUmunhum in forum Linux Programming
    Replies: 0
    Last Post: 11-18-2008, 07:02 PM
  5. producing c/c++ code from flowcharts,pseudo code , algorithims
    By rohit83.ken in forum C++ Programming
    Replies: 3
    Last Post: 02-20-2008, 07:09 AM