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

Interrupt with motor drive and encoder 18f2550 solved

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
doguhanpala



Joined: 05 Oct 2016
Posts: 120

View user's profile Send private message

Interrupt with motor drive and encoder 18f2550 solved
PostPosted: Wed Oct 12, 2016 8:07 am     Reply with quote

Hello

I try to drive a motor and stop it with the data that i collect from optical encoder. I want to do it with interrupt. I have a few questions.

First of all, i did not get it how the pic knows which function is the interrupt function. Does it understand when the function ends with ISR() ?
If i use 2 encoders and write 2 interrupt functions like external_interrupt1_isr() and external_interrupt2_isr(), how will it understand which interrupt function will start with 2 different data ?

My last question. I wrote the code below. It seems the interrupt function doesn't work. I connected an led to pin b2 and it does not light.

Note: I checked the motor and circuit with different software and they work correctly. I checked the interrupt code too. It works also. I added them below. The problem is i cannot mix them. Something is wrong. Any ideas?

Note2: I use L293d for motor driving if it makes any difference.

Doğuhan

this is the interrupt code. it works.

Code:
#include <18F2550.h>
#fuses INTRC_IO,HS, NOWDT, PUT, NOLVP, HSPLL,NOMCLR,NOPROTECT,NOLVP,NODEBUG,NOBROWNOUT,USBDIV,PLL5,CPUDIV1,VREGEN,NOPUT
#device ADC=10
#use delay(clock=4000000)
#int_EXT


void external_interrupt_isr()
{
   output_high(PIN_B2);  //open interrupt led
}

void main()
{
   //setup lines
   set_tris_b(0b1);       //b0 is input, the voltage from the switch goes there
   ext_int_edge(L_TO_H); 
   setup_oscillator(OSC_4MHZ);
   ENABLE_INTERRUPTS(INT_EXT);
   ENABLE_INTERRUPTS(GLOBAL);

      while(TRUE)
      {
         output_low(PIN_B2);  //close the interrupt led
         output_high(PIN_B1); //blink led1
         delay_ms(500);
         output_low(PIN_B1);
         delay_ms(500);
         
      }

}


this is the motor drive code. it also works.

Code:

#include <18F2550.h>
#fuses INTRC_IO, NOWDT, PUT, NOLVP, HSPLL,NOMCLR,NOPROTECT,NOLVP,NODEBUG,NOBROWNOUT,USBDIV,PLL5,CPUDIV1,VREGEN
#device ADC=10
#use delay(clock=4000000)
#define motor1_pin1 PIN_A1   //pin2 on l293d
#define motor1_pin2 PIN_A2   //pin7 on l293d

#int_EXT

unsigned int speed=100;

//motor komutları

void motor1_Forward()  //motor 1 ileri
   {
      OUTPUT_HIGH(motor1_pin1);
      OUTPUT_LOW(motor1_pin2);
   }
   
void motor1_Backward()  //motor 1 geri
   {
      OUTPUT_HIGH(motor1_pin2);
      OUTPUT_LOW(motor1_pin1);
   }

void motor1_Stop()   //motor 1 dur
   {     
      OUTPUT_LOW(motor1_pin2);
      OUTPUT_HIGH(motor1_pin1);
      delay_ms(10);
      OUTPUT_HIGH(motor1_pin2);
      OUTPUT_LOW(motor1_pin1);
      delay_ms(10);
      OUTPUT_LOW(motor1_pin2);
      OUTPUT_LOW(motor1_pin1);
   }


void main()
   { 
   
      set_tris_a(0x00000001);                   
      set_tris_b(0b11);
      setup_adc_ports(AN0);
      setup_adc(ADC_CLOCK_INTERNAL);
      setup_oscillator(OSC_4MHZ);
      setup_timer_2(T2_DIV_BY_16,250,1);
      setup_CCP1(CCP_PWM); // pin 1 on l293d
      set_pwm1_duty(speed);
     
     
   
      while(TRUE)
      {
         motor1_Forward();
      }
   }
   
   


the last one, ithink the distance_counter does not increase, which means the interrupt function doesnt work. i could not find the problem.

Code:
#include <18F2550.h>
#fuses INTRC_IO, NOWDT, PUT, NOLVP, HSPLL,NOMCLR,NOPROTECT,NOLVP,NODEBUG,NOBROWNOUT,USBDIV,PLL5,CPUDIV1,VREGEN
#device ADC=10
#use delay(clock=4000000)
#define encoder_data PIN_A0
#define motor1_pin1 PIN_A1   //pin2 on l293d
#define motor1_pin2 PIN_A2   //pin7 on l293d

#int_EXT
unsigned int distance_counter=0;

void external_interrupt_isr()
{
   distance_counter=distance_counter+1;
}


unsigned int speed=100;

//motor functions

void motor1_Forward() 
   {
      OUTPUT_HIGH(motor1_pin1);
      OUTPUT_LOW(motor1_pin2);
   }
   
void motor1_Backward() 
   {
      OUTPUT_HIGH(motor1_pin2);
      OUTPUT_LOW(motor1_pin1);
   }

void motor1_Stop()   
   {     
      OUTPUT_LOW(motor1_pin2);
      OUTPUT_HIGH(motor1_pin1);
      delay_ms(10);
      OUTPUT_HIGH(motor1_pin2);
      OUTPUT_LOW(motor1_pin1);
      delay_ms(10);
      OUTPUT_LOW(motor1_pin2);
      OUTPUT_LOW(motor1_pin1);
   }


void main()
   { 
   
      set_tris_a(0x00000001);                   
      set_tris_b(0x00000001);
      setup_adc_ports(AN0);
      setup_adc(ADC_CLOCK_INTERNAL);
      setup_oscillator(OSC_4MHZ);
      setup_timer_2(T2_DIV_BY_16,250,1);
      setup_CCP1(CCP_PWM); // pin 1 on l293d
      set_pwm1_duty(speed);                     
      ext_int_edge(L_TO_H); 
      setup_oscillator(OSC_4MHZ);
      ENABLE_INTERRUPTS(INT_EXT);
      ENABLE_INTERRUPTS(GLOBAL);
   
      output_high(PIN_B2); //led blink once to see the program started
      delay_ms(1000);
      output_low(PIN_B2);
      delay_ms(1000);
   
      while(TRUE)
      {
         
         if(distance_counter<=40)
            {
               motor1_Forward();
            }
         else
            {
               motor1_Stop();
               delay_ms(2000);
               output_high(PIN_B2); 
            }
         
      }
   }
   
   


Last edited by doguhanpala on Fri Oct 21, 2016 1:24 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Wed Oct 12, 2016 8:21 am     Reply with quote

The #INT_EXT line says that the routine on the following line is the handler for the EXT isr.

Though it should just ignore the white-space lines, the syntax should be:

Code:


#INT_EXT //This declares that the following subroutine is for INT_EXT
void external_interrupt_isr(void)
{
   output_high(PIN_B2);  //open interrupt led
}


The handler for INT_EXT1, would want #INT_EXT1 in front of it etc...

Don't put variable declarations between this and the function

Your oscillator settings are wrong. You currently have three oscillators setup.
INT_RC (use the internal oscillator)
HS use the external crystal directly
HSPLL use the external crystal with a PLL

Duh.....

I've pointed out how the settings work, only a few days ago in this thread:
<http://www.ccsinfo.com/forum/viewtopic.php?t=55555>

You also have both the power up time, and no power up timer selected.
doguhanpala



Joined: 05 Oct 2016
Posts: 120

View user's profile Send private message

PostPosted: Thu Oct 13, 2016 1:11 am     Reply with quote

I deleted the HS and HSPLL. Still doesn't work. And the other 2 code works perfectly even though i did not change the fuses or the other things you mentioned. Why do they work correctly?

and thanks for your help. i really appreciate it. i am dealing with pic with max 2 weeks and since i don't know how to choose fuses, or what is timer, i find the codes i need. So fuses can be ridiculous.

I have one more question. If i want to use 2 interrupts same time, can i write this?
Code:

#INT_EXT1 //This declares that the following subroutine is for INT_EXT
void external_interrupt_isr(void)
{
   output_high(PIN_B2);  //open interrupt led
}
#INT_EXT2
void external_interrupt_isr(void)
{
   output_low(PIN_B2);  //close interrupt led
}


Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Thu Oct 13, 2016 1:31 am     Reply with quote

Yes, except the remark is now wrong. INT_EXT1, is for EXT1, not for EXT, and it can't then work, since you are using pin B2 as an output, and also as an input.

INT_EXT, is pin B0
INT_EXT1 is pin B1
INT_EXT2 is pin B2

You have this latter pin being both driven high/low, and also used as an interrupt input.

Working. Luck.
The fuses 'or' together, so the result may be acceptable or may not. If you look at the end of the .LST file, it'll show what really is being sent to the chip.

There is also FSCM. This is a system where if the specified oscillator doesn't work, the chip will 'fall back' and run off the internal oscillator (fail safe clock monitor). So chips can work a bit, but are not working as they should....

You will find that things that are wrong, can sometimes work. More often than not they will have later problems. What actually _is_ your clock?. Do you have a crystal?.
doguhanpala



Joined: 05 Oct 2016
Posts: 120

View user's profile Send private message

PostPosted: Thu Oct 13, 2016 1:35 am     Reply with quote

Ttelmah wrote:
Yes, except the remark is now wrong. INT_EXT1, is for EXT1, not for EXT, and it can't then work, since you are using pin B2 as an output, and also as an input.

INT_EXT, is pin B0
INT_EXT1 is pin B1
INT_EXT2 is pin B2

You have this latter pin being both driven high/low, and also used as an interrupt input.


thank you so much!
doguhanpala



Joined: 05 Oct 2016
Posts: 120

View user's profile Send private message

PostPosted: Fri Oct 14, 2016 5:12 am     Reply with quote

Ttelmah wrote:
Yes, except the remark is now wrong. INT_EXT1, is for EXT1, not for EXT, and it can't then work, since you are using pin B2 as an output, and also as an input.

INT_EXT, is pin B0
INT_EXT1 is pin B1
INT_EXT2 is pin B2

You have this latter pin being both driven high/low, and also used as an interrupt input.

Working. Luck.
The fuses 'or' together, so the result may be acceptable or may not. If you look at the end of the .LST file, it'll show what really is being sent to the chip.

There is also FSCM. This is a system where if the specified oscillator doesn't work, the chip will 'fall back' and run off the internal oscillator (fail safe clock monitor). So chips can work a bit, but are not working as they should....

You will find that things that are wrong, can sometimes work. More often than not they will have later problems. What actually _is_ your clock?. Do you have a crystal?.


I will use crystal. Just not for now. For this part of project i don't use crystal. I am trying to do my part properly. My friends will complete their parts and the crystal will take place on their parts. When we mix the parts we do, i will change the fuses and stop using internal clock.
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

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

PostPosted: Wed Oct 19, 2016 6:28 pm     Reply with quote

Don't have too much to add after Mr Ttelmah posts, but your sentence:
Quote:
since i don't know how to choose fuses, or what is timer...

How you can write software if the sentence above is true?
You need to invest time to read (and understand) the data sheet first!!!

Proposing you to write first a short program using one of the timers to make a led to blink every second.

Best wishes
Joe
doguhanpala



Joined: 05 Oct 2016
Posts: 120

View user's profile Send private message

PostPosted: Wed Oct 19, 2016 11:53 pm     Reply with quote

gjs_rsdi wrote:
Don't have too much to add after Mr Ttelmah posts, but your sentence:
Quote:
since i don't know how to choose fuses, or what is timer...

How you can write software if the sentence above is true?
You need to invest time to read (and understand) the data sheet first!!!

Proposing you to write first a short program using one of the timers to make a led to blink every second.

Best wishes
Joe


First of all, thank you for your warning. I usually search what i need to write a software. For example i need to stop a motor when i press the button. First i search how to drive a motor. After watching videos and reading forums ianage it. When i make it i search external interrupts. After a bit of work and try i usually achieve what i need.

But i realised it is not the best way to do it. My softwares work so far but i know i am just saving the day.

Thank you for warning again.
Best wishes
Doğuhan
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Thu Oct 20, 2016 6:53 am     Reply with quote

Let's make some comments:

First thing is that the normal way to detect a quadrature encoder will be to use two of the 'interrupt on change' bits (B4 to B7). A quadrature encoder has two waveforms 90 degrees out of phase of each other, and to decode the four states, you want to be calling the scan code on all four edges that this involves (signals A, and B, each going high or low). Quadrature code has been posted here many times. Advantage of using the interrupt on change, is just one routine is needed to handle all four edges.

Then, as I have already pointed out, you cannot use USB with the internal oscillator (there are chips where you can - these have either much more accurate internal oscillators, so can do 'low speed' USB, using this - or have the ability to synchronise the USB to the clock coming from the master device). Now if you are attempting to produce some form of motor controlled by USB, you are not going to get very far without the USB.....

Then we have the oscillator/fuses question. There are dozens of tiny details in every PIC, that need to be understood. Things like just how poor the accuracy of the ADC will be when you use the supply as the reference. What clocks can be used for which jobs, what the limitations of speeds and voltage levels are. All of these need study. Though you don't have to know every page of the data sheet (things like just 'how' the memory is laid out, and what registers are where, are handled for you by the compiler), you need to be looking at the basics on the oscillator, fuses etc., and at the specifics of the peripherals you are trying to use.

Now, if you are doing anything like a PID design (so the motor accelerates and moves 'to' a specific location etc.), your code will need to become synchronous. Taking readings at a fixed interval, so it can adjust the motor PWM. Otherwise when timing changes, the movement will be erratic.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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