CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Motor Control Code
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Jammie1000000



Joined: 06 Nov 2015
Posts: 8

View user's profile Send private message

Motor Control Code
PostPosted: Fri Nov 06, 2015 2:46 pm     Reply with quote

Hi, I seem to be having some difficulty regarding my code. The hardware is set up correctly, i.e. i am receiving varying voltages from LDR's and IR sensors. However, I am not getting the motors to be controlled in the desired fashion (they are not doing anything). Any advice? I am using a PIC16F877a Microcontroller, 2 DC motors, 2 LEDS and 2 LDRs, 2 IR sensors.
Code:

#include <16f877a.h>        //set up microcontroller
#device ICD=TRUE
#fuses HS,NOLVP,NOWDT,PUT
#use delay (clock=20000000)

#define WHITE_LED_FRONT PIN_B6 //digital output      //define pin allocation
#define WHITE_LED_REAR PIN_B7 //digital output
#define LDR_FRONT PIN_E2  //analogue input Channel 7
#define LDR_REAR PIN_A1   //analogue input Channel 1
#define IR_LEFT PIN_E1    //analogue input Channel 6
#define IR_RIGHT PIN_E0    //analogue input Channel 5
#define POWER_ON PIN_A4     //digital input
#define MOTOR_FORWARD_LEFT PIN_B5  //digital output
#define MOTOR_REVERSE_LEFT PIN_B3 //digital output
#define MOTOR_FORWARD_RIGHT PIN_B2 //digital output
#define MOTOR_REVERSE_RIGHT PIN_B1 //digital output

#define CUTOFF_LDR_FRONT   128   //define cutoffs
#define CUTOFF_LDR_REAR    128
#define CUTOFF_IR_LEFT     128
#define CUTOFF_IR_RIGHT    128

void wait_for_power_on()   //set up power input
{
    while(input(POWER_ON));
    while(!input(POWER_ON));
    delay_ms(100);
}

void sensor(int sensor)   //define sensor function
{
    output_high(MOTOR_FORWARD_LEFT);    //switch off both motors
    output_high(MOTOR_FORWARD_RIGHT);
    output_high(MOTOR_REVERSE_LEFT);
    output_high(MOTOR_REVERSE_RIGHT);

    switch(sensor)
    {
        case 0: output_low(MOTOR_FORWARD_LEFT); output_low(MOTOR_REVERSE_LEFT); break; //Spin
        case 1: output_low(MOTOR_FORWARD_LEFT); output_low(MOTOR_FORWARD_RIGHT); break; //Move forward
        case 2: output_low(MOTOR_FORWARD_RIGHT); break; //Rotate left
        case 3: output_low(MOTOR_FORWARD_LEFT); break; //Rotate right
        case 4: output_low(MOTOR_REVERSE_LEFT); output_low(MOTOR_REVERSE_RIGHT); break; //Move back
    }
}

void main()
{

   int left_sensor;
    int right_sensor;
    int front_sensor;
    int rear_sensor;  //define sensor variables

    setup_adc_ports(All_Analog); //set up ADC
    setup_adc(ADC_CLOCK_INTERNAL);

    set_adc_channel(6);       //set up left sensor
    left_sensor = read_adc();

    set_adc_channel(5);       //set up right sensor
    right_sensor = read_adc();

    set_adc_channel(7);       //set up front sensor
    front_sensor = read_adc();

    set_adc_channel(1);       //set up rear sensor
    rear_sensor = read_adc();
   
    while(true)
    {
        wait_for_power_on(); //wait for power switch to be turned on
        delay_ms(1000);
        output_high(WHITE_LED_FRONT);   //switch on LED's for line sensors
        output_high(WHITE_LED_REAR);
    }

    while(true)
    {
        if(left_sensor<CUTOFF_IR_LEFT)   //Opponent seen on left sensor

            if(right_sensor<CUTOFF_IR_RIGHT) //Opponent in front

               sensor(1); //move forward

             else  //opponent on left

               sensor(2);    //rotate left

         else if(right_sensor<CUTOFF_IR_RIGHT) //opponent seen on right side

               sensor(3); //rotate right

         else if(front_sensor<CUTOFF_LDR_FRONT) //line seen on front LDR

                sensor(4);  // move backwards

          else if(rear_sensor<CUTOFF_LDR_REAR) //line seen on rear LDR

                sensor(1);  //move forwards

          else

                sensor(0); //spin

    }

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 06, 2015 3:06 pm     Reply with quote

Quote:
However, I am not getting the motors to be controlled in the desired
fashion (they are not doing anything).

Just make a very simple program without all the input sensor code.
Turn on one motor. Does it work ? If not, then look closely at your
motor control circuit. Post a link to the schematic of the circuit.

Also, your A/D code is wrong. You need to make the changes shown
in bold below:
Quote:

setup_adc_ports(All_Analog); //set up ADC
setup_adc(ADC_CLOCK_DIV_32);

set_adc_channel(6); //set up left sensor
delay_us(20);
eft_sensor = read_adc();

set_adc_channel(5); //set up right sensor
delay_us(20);
right_sensor = read_adc();

set_adc_channel(7); //set up front sensor
delay_us(20);
front_sensor = read_adc();

set_adc_channel(1); //set up rear sensor
delay_us(20);
rear_sensor = read_adc();

The 20us delay time is shown in EQUATION 11-1: ACQUISITION TIME
in the 16F877 data sheet.

The A/D clock divisor of 32 is shown in TABLE 11-1: TAD vs. MAXIMUM
DEVICE OPERATING FREQUENCIES (STANDARD DEVICES (C)) in the
16F877 data sheet.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Fri Nov 06, 2015 3:15 pm     Reply with quote

the choice of the 877 is a bad one if you ever intend to manufacture more than ONE of these. based on price and based on performance. the 877 is a "school kid" part not a design-for-manufacturing part.

the 16f887 for a superior device at less than 1/2 the price.

in the 877 data sheet did you read this ?

Quote:

re the ADC clock selection ......
e 1: The RC source has a typical TAD time of 4 µs but can vary between 2-6 µs.
2: When the device frequencies are greater than 1 MHz, the RC A/D conversion clock source is only
recommended for Sleep operation.


were you going to use it in sleep?
the process of getting your sensors is assured to be SLOWER than need be
and much noisier from reading to reading than it has to be.
But that doesn't matter either ;-))
look closely at your code !

After that initial reading of the ADC -
you enter a while loop and never read the adc again.

whats with THAT ???

what kind of decisions does that make for ?
------------------------

(( i see PCM_P commented on the above as i was writing))
also
sensor() is CRAZY -
look at what you are doing to those (drive?) lines !!!

switches like what you program are NASTY into reactive loads.

think about what happens if sensor is called with either motor ON -and
then re-selected to be ON again?
ouch.....

itd
your code is a MESS..........
wangine



Joined: 07 Jul 2009
Posts: 98
Location: Curtea de Arges, Romania

View user's profile Send private message Send e-mail Yahoo Messenger

PostPosted: Fri Nov 06, 2015 5:39 pm     Reply with quote

also , two while(1) loops
Code:
    while(true)
    {
        wait_for_power_on(); //wait for power switch to be turned on
        delay_ms(1000);
        output_high(WHITE_LED_FRONT);   //switch on LED's for line sensors
        output_high(WHITE_LED_REAR);
    }
Your code will never go out from here , just turn on the leds, wait and ..... again.
Jammie1000000



Joined: 06 Nov 2015
Posts: 8

View user's profile Send private message

Motor Control Code
PostPosted: Sat Nov 07, 2015 11:39 am     Reply with quote

I have altered the code (see below) and I have also attached the circuit design.

Code:

#include <16f877a.h>        //set up microcontroller
#device ICD=TRUE
#fuses HS,NOLVP,NOWDT,PUT
#use delay (clock=20000000)

#define WHITE_LED_FRONT PIN_B6 //digital output      //define pin allocation
#define WHITE_LED_REAR PIN_B7 //digital output
#define LDR_FRONT PIN_E2  //analogue input Channel 7
#define LDR_REAR PIN_A1   //analogue input Channel 1
#define IR_LEFT PIN_E1    //analogue input Channel 6
#define IR_RIGHT PIN_E0    //analogue input Channel 5
#define POWER_ON PIN_B4     //digital input
#define MOTOR_FORWARD_LEFT PIN_B5  //digital output
#define MOTOR_REVERSE_LEFT PIN_B3 //digital output
#define MOTOR_FORWARD_RIGHT PIN_B2 //digital output
#define MOTOR_REVERSE_RIGHT PIN_B1 //digital output

#define CUTOFF_LDR_FRONT   128   //define cutoffs
#define CUTOFF_LDR_REAR    128
#define CUTOFF_IR_LEFT     128
#define CUTOFF_IR_RIGHT    128

void wait_for_power_on()   //set up power input
{
    while(input(POWER_ON));
    delay_ms(100);
}

void sensor(int sensor)   //define sensor function
{
    output_high(MOTOR_FORWARD_LEFT);    //switch off both motors
    output_high(MOTOR_FORWARD_RIGHT);
    output_high(MOTOR_REVERSE_LEFT);
    output_high(MOTOR_REVERSE_RIGHT);

    switch(sensor)
    {
        case 0: output_low(MOTOR_FORWARD_LEFT); output_low(MOTOR_REVERSE_LEFT); break; //Spin
        case 1: output_low(MOTOR_FORWARD_LEFT); output_low(MOTOR_FORWARD_RIGHT); break; //Move forward
        case 2: output_low(MOTOR_FORWARD_RIGHT); break; //Rotate left
        case 3: output_low(MOTOR_FORWARD_LEFT); break; //Rotate right
        case 4: output_low(MOTOR_REVERSE_LEFT); output_low(MOTOR_REVERSE_RIGHT); break; //Move back
    }
}

void main()

    int left_sensor;
    int right_sensor;
    int front_sensor;
    int rear_sensor;  //define sensor variables

    setup_adc_ports(All_Analog); //set up ADC
    setup_adc(ADC_CLOCK_DIV_32);

   
    while(true)
    {
    set_adc_channel(6);       //set up left sensor
    delay_us(20);
    left_sensor = read_adc();

    set_adc_channel(5);       //set up right sensor
    delay_us(20);
    right_sensor = read_adc();

    set_adc_channel(7);       //set up front sensor
    delay_us(20);
    front_sensor = read_adc();

    set_adc_channel(1);       //set up rear sensor
    delay_us(20);
    rear_sensor = read_adc();

        wait_for_power_on(); //wait for power switch to be turned on
        delay_ms(5000);
        output_low(WHITE_LED_FRONT);   //switch on LED's for line sensors
        output_low(WHITE_LED_REAR);
   
        if(left_sensor<CUTOFF_IR_LEFT)   //Opponent seen on left sensor

            if(right_sensor<CUTOFF_IR_RIGHT) //Opponent in front

               sensor(1); //move forward

             else  //opponent on left

               sensor(2);    //rotate left

         else if(right_sensor<CUTOFF_IR_RIGHT) //opponent seen on right side

               sensor(3); //rotate right

         else if(front_sensor<CUTOFF_LDR_FRONT) //line seen on front LDR

                sensor(4);  // move backwards

          else if(rear_sensor<CUTOFF_LDR_REAR) //line seen on rear LDR

                sensor(1);  //move forwards

          else

                sensor(0); //spin
    }

}


https://drive.google.com/file/d/0Byue2b0J82tjTXIxcUR3YmxDVXc/view?usp=sharing
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Nov 07, 2015 2:30 pm     Reply with quote

The schematic shows an L293D motor controller chip. You don't show the
PIC in that schematic. Also, you don't show the +5v power supply.
You're not showing us enough.

In your code, you have a routine where you wait for the power switch:
Code:
void wait_for_power_on()   //set up power input
{
    while(input(POWER_ON));
    delay_ms(100);
}

You are waiting until Pin B4 goes to a low level. Then you will exit the
while() loop above. Where is this shown in your schematic ? Where is
there a pin that goes to a low level (ground) when power is turned on ?

I still say you need to setup a test where you turn on one motor just
to see if it will run. Don't look at sensors or anything else. You need
to do this test. It will prove:
1. That your hardware is correct or not.
2. That you have the correct software method of controlling the L293D
to enable turning on a motor.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sat Nov 07, 2015 6:10 pm     Reply with quote

Code:
void sensor(int sensor)   //define sensor function

I also suggest you change these names to be more in line with the actual function they perform:
Code:
void move(int direction)   // Set motors to move in given direction


Even nicer when you use defines or an enum for the direction values.
A line like:
Code:
sensor(1); //move forward

then becomes:
Code:
#define FORWARD    1

move(FORWARD);
Note that no comments are needed anymore to explain what's happening; the code has become self documenting.
Jammie1000000



Joined: 06 Nov 2015
Posts: 8

View user's profile Send private message

Motor Control Code
PostPosted: Mon Nov 09, 2015 6:43 am     Reply with quote

The motors will turn if a simple output is made to the H-bridge. However, with my code, there is approximately a 3.3V going into all 4 of the H-bridge inputs. Obviously, this is why the motors aren't turning. With regards to the code, I know it can do with a bit of tidying up. I just want to get the code to do what I want it to do first before cleaning it up.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Mon Nov 09, 2015 8:37 am     Reply with quote

This almost certainly goes back to this comment from PCM_Programmer:
Quote:

You are waiting until Pin B4 goes to a low level. Then you will exit the
while() loop above. Where is this shown in your schematic ? Where is
there a pin that goes to a low level (ground) when power is turned on ?


Unless this pin is seen going low, your code will leave the driver pins still set as inputs, so they will float to whatever the L293D produces on it's inputs when no connection is made. Typically about 3v.
Jammie1000000



Joined: 06 Nov 2015
Posts: 8

View user's profile Send private message

Motor Control Code
PostPosted: Tue Nov 10, 2015 3:58 pm     Reply with quote

I have brought the power on into the main while code, so should it not loop in this? I.e. checking to see if power is on, making sure the LED's are lit, then controlling the motor? I have attached the flow chart of what I want the microcontroller to do.

https://drive.google.com/file/d/0Byue2b0J82tjaUl1bXB5d0tSV2s/view?usp=sharing
wangine



Joined: 07 Jul 2009
Posts: 98
Location: Curtea de Arges, Romania

View user's profile Send private message Send e-mail Yahoo Messenger

Re: Motor Control Code
PostPosted: Tue Nov 10, 2015 10:25 pm     Reply with quote

Jammie1000000 wrote:
I have brought the power on into the main while code, so should it not loop in this? I.e. checking to see if power is on, making sure the LED's are lit, then controlling the motor? I have attached the flow chart of what I want the microcontroller to do.

According with your flowchart should add a _status_power_flag_ in your power function if you want to follow that chart. All loop functions will check that flag otherwise your power function don't make sense.
Also my advice is to clean up all your code and to start add, all functions, step by step like your chart show. I don't think will take more that 20 min
First off all be sure the motor or motors running, and only after that can add the conditions, otherwise you will stay forever to think why...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Nov 10, 2015 11:24 pm     Reply with quote

Code:
#define POWER_ON   PIN_B4     

Post a schematic that shows the circuit that is connected to Pin B4 on the PIC.

Post a schematic that shows your PIC and all external circuits.
Jammie1000000



Joined: 06 Nov 2015
Posts: 8

View user's profile Send private message

Motor Control Code
PostPosted: Thu Nov 12, 2015 11:12 am     Reply with quote

This is the circuit layout. When the switch at B4 is on, the code should loop, asking whether there is an object in front or the LDR's change voltage. Then the motors should turn one way depending on what is coming in from the sensors.

https://drive.google.com/file/d/0Byue2b0J82tjUmU1OG9qSG16ZjA/view?usp=sharing
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Nov 12, 2015 2:04 pm     Reply with quote

Your schematic is very low resolution. Zooming in just makes it harder
to read. Your circuit appears to look like this:
Code:
                     
            NC      +V(+5v)
           /o        |
Pic       /          |             _____
pin -----/  o--------o----->|-----|_____|-------
B4          NO            Led     220 ohms     |   
                                             -----
                                              --- Gnd

This means pin B4 will either be floating or be connected to +5v.
"Floating" means the pin has nothing connected to it, and could be
any value. It might read a logic 0, or if the switch was previously pressed
for just a short time, it could easily stay at a high logic level and your
PIC would read that as a logic 1.

Also, the switch has nothing to do with "power on". It doesn't control
the power. It's more like a "Start" switch, that you press to tell the
PIC to begin running the motor control program.

You should remove your existing switch circuit. You need to change it
to a Start switch circuit that looks like this:
Code:
           +5v
            |
            <
            > 4.7K      NC 
            <          /o   
To          |         /
PIC --------o--------/   o--------
pin B4                   NO      |             
                               ----- 
                                --- Gnd   
                                 -                 



Then change your "power on" function to this:
Code:

#define START_SWITCH  PIN_B4

void wait_for_start(void) 
{
while(input(START_SWITCH));  // Wait until start button is pushed
}

This routine will wait in a loop until a logic 0 is read from Pin B4.
The 4.7K pullup will provide a logic 1 until the switch is pressed,
and then the PIC will read a logic 0 (ground). Then the routine
will leave the while() loop and return to the main() code and
your motor control code can begin to run.
Jammie1000000



Joined: 06 Nov 2015
Posts: 8

View user's profile Send private message

Motor control code
PostPosted: Thu Nov 12, 2015 2:55 pm     Reply with quote

The power on doesn't seem to be a problem. When the button is pressed, the leds come on. The problem seems to be the motor control and I'm getting 3v from each of the four motor outputs into the h bridge.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group