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

Pic does not send signal to servos

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



Joined: 26 Feb 2018
Posts: 2

View user's profile Send private message

Pic does not send signal to servos
PostPosted: Mon Feb 26, 2018 11:28 pm     Reply with quote

I'm new to this, I would like some help. I'm making a robot arm with servos. It should have the position set by entering the degree of movement from a 4x4 matrix keyboard. The degrees should be displayed on an LCD.
I have a problem because the entered degrees are displayed on the lcd, but the pic does not output to the servos.

I am using a PIC18F4550.

I hope I have your help, I post my code below...
Code:

#include <18f4550.h>
#device ICD = TRUE
#device ADC=10               
#use delay (clock=48000000)

#use i2c(Master,Fast=100000, sda=PIN_D6, scl=PIN_D7,force_sw)

#include <i2c_Flex_LCD.h>   
#include <kb4x4.h> //LIBRERIA DE TECLADO

#fuses HSPLL,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,USBDIV,PLL5,CPUDIV1,DEBUG,ICSP1 // configura fuses

#USE FAST_IO(B)

#byte trisb=0x86
#byte portb=0x06
#byte trisc=0x87
#byte portc=0x07

#define use_portb_kbd TRUE             //Configuración puerto b control teclado

#bit  Bit_PWM0 =  PORTC.0              //Bit 0 puerto C Salida modulación 0
#bit  Bit_PWM1 =  PORTC.1              //Bit 1 puerto C Salida modulación 1
#bit  Bit_PWM2 =  PORTC.2              //Bit 2 puerto C Salida modulación 2
#bit  Bit_PWM3 =  PORTC.3              //Bit 3 puerto C Salida modulación 3
#bit  Bit_PWM4 =  PORTC.4              //Bit 4 puerto C Salida modulación 4
#bit  Bit_PWM5 =  PORTC.5              //Bit 5 puerto C Salida modulación 5
#bit  Bit_PWM6 =  PORTC.6              //Bit 6 puerto C Salida modulación 6
#bit  Bit_PWM7 =  PORTC.7              //Bit 7 puerto C Salida modulación 7

/********************** Prototipos de las funciones ***************************/

void main (void);             //función principal
void generacion_pwm (void);   //genera señales moduladas para control de servos
void presentacion (void);     //mensaje de presentación

/********************** Variables para generación PWM *************************/

int8 PWM0=0,PWM1=0,PWM2=0,PWM3=0,PWM4=0,PWM5=0,PWM6=0,PWM7=0; //Valores de las señales PWM
int8 control_PWM=0;

/******************************************************************************/
/******************* FUNCIÓN GENERACIÓN MODULACIONES PWM **********************/

#int_Timer0

void generacion_pwm(){
   
   control_PWM++;                //Incremento cada rebose del timer0
 
   if (control_PWM==0){          //inicio del ciclo con todos los pulsos pwm a 1
      Bit_PWM0=1;     
      Bit_PWM1=1;
      Bit_PWM2=1;
      Bit_PWM3=1;
      Bit_PWM4=1;
      Bit_PWM5=1;
      Bit_PWM6=1;
      Bit_PWM7=1;
   }
   //Finalizará el pulso de modulación según el valor del correspondiente pwm
   if (control_PWM==PWM0) Bit_PWM0=0;
   if (control_PWM==PWM1) Bit_PWM1=0;
   if (control_PWM==PWM2) Bit_PWM2=0;
   if (control_PWM==PWM3) Bit_PWM3=0;
   if (control_PWM==PWM4) Bit_PWM4=0;
   if (control_PWM==PWM5) Bit_PWM5=0;
   if (control_PWM==PWM6) Bit_PWM6=0;
   if (control_PWM==PWM7) Bit_PWM7=0;
   
   set_timer0(255);                    //Carga del contador
}
   
/******************************************************************************/
/************************* PRESENTACIÓN LCD ***********************************/

void presentacion (){
   lcd_clear();  //Clear Display
   printf(LCD_PUTC,"\1%s","Introduce"); 
   printf(LCD_PUTC,"\2%s"," num. de servo "); 
}

/******************************************************************************/
/******************** FUNCIÓN PRINCIPAL ***************************************/

void main(){
 
  set_tris_c(0b00000000);  // Configura PIN_C1 como salida
 
   int x;                        //Valor ASCII de la tecla pulsada
   int tecla;                    //Valor numérico de la tecla pulsada
   int servo;                    //Número de servo
   int16 angulo;                 //Ángulo del servo
   int16 centenas;               //variable para las centenas del ángulo
   int decenas,unidades;         //Variable para las decenas y unidades del ángulo
   int pwm;                      //valor de la modulación por teclado
   
   trisc=0x00;                   //Puerto C como salida de datos
   
   pwm0=7;                      //Impulso de 0,8 msg de pwm0 posición 0º
   pwm1=7;                      //Impulso de 0,8 msg de pwm1 posición 0º
   pwm2=7;                      //Impulso de 0,8 msg de pwm2 posición 0º
   pwm3=7;                      //Impulso de 0,8 msg de pwm3 posición 0º
   pwm4=7;                      //Impulso de 0,8 msg de pwm4 posición 0º
   pwm5=7;                      //Impulso de 0,8 msg de pwm5 posición 0º
   pwm6=7;                      //Impulso de 0,8 msg de pwm6 posición 0º
   pwm7=7;                      //Impulso de 0,8 msg de pwm7 posición 0º
   
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32);         //Configuración interrupción generación PWM
   enable_interrupts(INT_TIMER0);    //Habilitación interrupción generación pwm
   enable_interrupts(GLOBAL);        //Habilitación de las interrupciones
   
   port_b_pullups(TRUE);   //Habilitación resistencias pullups puerto b
   lcd_init();             //Inicialización del lcd
   kbd_init();             //Inicialización del teclado
   
   presentacion ();        //Muestra mensaje de inicio en lcd
   
   while (true){
       
      x=kbd_getc();                    //En "x" valor ASCII de la tecla pulsada
      if (x!=0&&x!='9'&&x!='8'&&x!='*'&&x!='#'){ //Si se pulsa tecla numérica 0 a 7 ...
         servo=x-48;            //Valor ASCII se pasa a valor numerico de servo
         printf(lcd_putc,"\fServo = %d\n", servo); //...muestra el valor pulsado
          printf(LCD_PUTC,"\2%s","introduce angulo");
         
         while (x!='*'){            //Espera a introducir ángulo y aceptar con *
            x=kbd_getc();
            tecla=x-48;
            if (x!=0&&x!='*'&&x!='#'){    //Solo se toman los valores numéricos
               //A cada tecla pulsada se desplaza posición decimal y se muestra
               centenas=decenas;
               decenas=unidades;
               unidades=tecla;
               printf(lcd_putc,"\f Angulo = %ld%d%d\n", centenas, decenas, unidades);
                printf(LCD_PUTC,"\2%s","* para aceptar");
            }
         }
       
       angulo=(centenas*100)+(decenas*10)+unidades;
       if (angulo>180) angulo=180;    //No acepta valores >180º
       pwm=(angulo/13)+7;             //Ajuste modulación en función del valor introducido
       centenas=decenas=unidades=0;   
       
       //Según número de servo introducido se le aplica el ángulo elegido
       switch(servo){
       case 0: pwm0=pwm; break;
       case 1: pwm1=pwm; break;
       case 2: pwm2=pwm; break;
       case 3: pwm3=pwm; break;
       case 4: pwm4=pwm; break;
       case 5: pwm5=pwm; break;
       case 6: pwm6=pwm; break;
       case 7: pwm7=pwm; break;
       }
       printf(lcd_putc,"\fServo  %d\n", servo);
       printf(lcd_putc," Angulo  %ld", angulo);
       delay_ms(200);
       presentacion();
      }
   }
}

_________________
Roy
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Tue Feb 27, 2018 2:04 am     Reply with quote

First thing:
Code:

#byte trisb=0x86
#byte portb=0x06
#byte trisc=0x87
#byte portc=0x07

These are all wrong. The values you have are for a PIC16, not a PIC18. This is why we always say 'use the register names':
Code:

#byte trisb=getenv("SFR:TRISB")

etc..

So the code is not going to work.

Then there is a problem with your timer interrupt. The timer is running in 16bit mode. So it'll count from 255 (which you set it to in the interrupt), to 65535, then interrupt at 65536 (0). So 65281 counts. The timer is running off Fosc/(4*32) 375000Hz, so will interrupt every 375000/65281 = 5.744* per second. Going to be over a second pulse at a count of 7.....
If you were running in 8bit mode, much faster, but it'll almost certainly never then get out of the interrupt. Just one count of 32 machine cycles between interrupts... :(

If '7' is meant to be the zero degree output (1mSec), then you want an interrupt at 143uSec. 1714 counts of the Fosc/4 feeding the timer. Using /32, 53 counts. So:

Code:

   setup_timer_0(T1_INTERNAL|T0_DIV_32|T0_8_BIT);
   //select 8bit mode
   //for the timer setup, and then:
   set_timer0(203);
   //to make it trigger at the interval required

Should give about the right timing.
Rodrigo



Joined: 26 Feb 2018
Posts: 2

View user's profile Send private message

Ayuda...
PostPosted: Tue Feb 27, 2018 1:55 pm     Reply with quote

Friend, I have already modified the register names and it still does not output to the servos.

Could you explain to me more, or help me with the code in the timer part?
Thank you!!!
_________________
Roy
guy



Joined: 21 Oct 2005
Posts: 297

View user's profile Send private message Visit poster's website

PostPosted: Fri Mar 02, 2018 1:29 pm     Reply with quote

Hola Rodrigo.
Start by checking that the registers and setup are correct - send 1ms pulse every 20ms to one servo (no interrupts):
output_high()
delay_ms(1)
output_low()
delay_ms(19)

If the setup is working ok you can debug the timer and logic easily with an oscilloscope.
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