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

PWM with bluetooth

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



Joined: 12 Apr 2015
Posts: 7

View user's profile Send private message

PWM with bluetooth
PostPosted: Mon Apr 13, 2015 6:47 pm     Reply with quote

Hey there, I'm working on a school project and I need some help at this point. I'm making a bluetooth controlled car, this must be able to work with three different speeds - low, medium, high-, and it's speed must be measured and printed on the same app that controls it.

The app is not the problem, I have problems coding the PWM, and I'm using the TIMER1 to count the pulses delivered by an H21A1 optical sensor, I'm not sure if the bluetooth data receive/transmit program is ok. I would really appreciate any possible help.

I'm using a PIC16F628A.

Don't mind the comments in spanish, sorry .

Code:

#include <Carrito sensor.h>
#include <stdio.h>
#use fast_io(B)
#use RS232(baud=9600, xmit=PIN_B2, rcv=PIN_B1)   //Declaramos uso del UART y su baudaje, pines de transmisión y recepción
long pulsos;      // Declaramos una variale para poder guardar valores grandes, en este caso las pulsaciones
long rpm=0;
float vlineal=0;
float kxh=0;
int velocidad;
unsigned char Dato=0;



/*Comunicación serial*/
//Función de Interrupción por Recepción

static void interrupt isr(void){   //Funcion para interrupcion por recepcion de la usart // Interrupt Service Routines
   if(kbhit()==1){               //Se cumple si entra un dato por el pin receptor de la USART

   Dato=getc();         //Si llega un dato guardalo en el registro Dato
   }
}

//Inicio de programa de comunicación serial, este esta diseñado en MPLAB


//SECCIÓN DE FUNCIONES
     
//Función de Inicializacion de Módulo UART
void UARTinit9600 (void)
{

   TXSTA= 0B00100100;       // 0B00100100;         // = 0X22 // TXEN=1, BRGH=1 --> Habilita Transmisión y Bajo Baudaje //
   RCSTA= 0B10010000;         // = 0X90 // SPEN=1, CREN=1 --> Habilita Puerto Serial y Recepción
   SPBRG=  25;            // BRGH=1
   
}

//Función de Inicializacion de las Interrupciones por Recepción
void InterruptsInit(void)
{
   enable_interrupts(GLOBAL);   // Habilitamos las Interrupciones Globales // BIT 7 - Registro INTCON
   enable_interrupts(PERIPH);  // Habilitamos las Interrupciones por Perifericos // BIT 6 - Registro INTCON
   enable_interrupts(int_rda);  // Habilitamos la Interrupcion por Recepcion del modulo USART l // BIT 5 - Registro RCIE
   RCIF=0;  // Apagamos la Bandera de Interrupcion // BIT 5 - Registro PIR1
   
}
   
   //Rutina de Configuración General del Microcontrolador
   void comunicacion_serial()
   {
   CMCON   = 0B00000111;


   //Eliminar posible LATCH o Basura en los Puertos
   PORTB   = 0B00000000; //Configuro el registro LATB     - Se elimina posible basura o latch en el Puerto B

   //FUNCIONES DE INICIALIZACION DE PERIFERICOS
  UARTinit9600();
  InterruptsInit();
   }


void controles (void){
   
   if (Dato=="n"){    //Aquí el carrito se mueve hacia el frente.
      output_high(PIN_A2);    //Primer motor avanza adelante.
      output_low(PIN_A3);           
      output_high(PIN_B4);    //Segundo motor avanza hacia adelante.
      output_low(PIN_B5);         
    }
     if (Dato=="s"){    //Aquí el carrito se mueve hacia el atrás.
      output_low(PIN_A2);       //Primer motor retrocede.
      output_high(PIN_A3);           
      output_low(PIN_B4);      //Segundo motor retrocede.
      output_high(PIN_B5);         
    }
    if (Dato=="e"){    //Aquí el carrito se mueve hacia la derecha.
      output_high(PIN_A2);     //Primer motor avanza adelante.
      output_low(PIN_A3);           
      output_low(PIN_B4);      //Segundo motor se detiene.
      output_low(PIN_B5);         
    }
    if (Dato=="o"){    //Aquí el carrito se mueve hacia la derecha.
      output_low(PIN_A2);     //Primer motor se detiene.
      output_low(PIN_A3);           
      output_high(PIN_B4);     //Segundo motor avanza adelante.
      output_low(PIN_B5);         
    }
    if (Dato=="x"){    //Aquí el carrito se mueve hacia la derecha.
      output_low(PIN_A2);     //Primer motor se detiene.
      output_low(PIN_A3);   
      output_low(PIN_B4);      //Segundo motor se detiene.
      output_low(PIN_B5);       
    }
}
 
void reset (void){   //Esto lo había puesto anteriormente en el ciclo while, y es que necesito esa interrupción 
                       //al 1 segundo para poder contar los pulsos por segundos y sacar la velocidad, no sé si se pueda hacer unafunción de interrupción interna.
    pulsos=0;         //Reiniciamos la variable a 0
    set_timer1(0);    //Reiniciamos la cuenta del timer a 0
}

void main(){
         //Registros de Configuración Inicial
   setup_timer_1(T1_EXTERNAL|RTCC_EXT_H_TO_L|RTCC_DIV_1);   //Se configura el Timer1 como contador para interrupciones externas por flancos de bajada, y registra cada pulso
   set_timer1(0);       //Iniciamos el timer en 0        *Los pulsos deben entrar por RB7*
   enable_interrupts(GLOBAL);    //Se habilitan las interrupciones globales
   set_tris_B(0x00);    //Declaramos entradas y salidas en RA
   set_tris_A(0x00);    //Declaramos entradas y salidas en RB
   output_low(PIN_A2);     //Primer motor detenido.
   output_low(PIN_A3);   
   output_low(PIN_B4);      //Segundo motor detenido.
   output_low(PIN_B5);
   
   /*PWM*/
     //Configuramos el  como generador de PWM
   setup_ccp1(CCP_PWM);
   setup_timer_2(T2_DIV_BY_1, 49, 1);
   port_b_pullups(TRUE);
   
   //Se toma en cuenta la dirección del carrito
      controles();
   
     
      //Velocidad alta
      if (Dato=="a"){         
            velocidad=50;
            delay_ms(250);
            set_pwm1_duty(velocidad);                   
      }
      //Velocidad baja
      if (Dato=="b"){       
            velocidad=8;
            delay_ms(250);
            set_pwm1_duty(velocidad);                 
      }
      //Velocidad media
      if (Dato=="m"){
          velocidad=25;
          delay_ms(250);
          set_pwm1_duty(velocidad);     
      }
   
   while(TRUE){
 
      pulsos=get_timer1();
      rpm=pulsos*60;
      vlineal=rpm*0.035*0.10472;
      kxh=(vlineal/1000)*3600;
      output_high(PIN_B0); //Deja encendido el Led para saber que el carrito esta encendido
      delay_ms(1000);   //Al final del retardo tenemos el número de pulsos por segundo
      reset();    //No sé si esté bien declarada asi la función para el reseteo del conteo del timer
     
       
       
   }

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 13, 2015 7:02 pm     Reply with quote

This won't work:
Quote:

if (Dato=="n"){ //Aquí el carrito se mueve hacia el frente.
output_high(PIN_A2); //Primer motor avanza adelante.
output_low(PIN_A3);
output_high(PIN_B4); //Segundo motor avanza hacia adelante.
output_low(PIN_B5);
}

In the C language, a character is represented by putting it in single-
quotes. If you use double-quotes, the compiled code will not do what
you want.

Do it like this:
Code:

if (Dato== 'n'){    //Aquí el carrito se mueve hacia el frente.
      output_high(PIN_A2);    //Primer motor avanza adelante.
      output_low(PIN_A3);           
      output_high(PIN_B4);    //Segundo motor avanza hacia adelante.
      output_low(PIN_B5);         
    }

Change all the other if() statements in your program to do it the same way.
DiegoCasso



Joined: 12 Apr 2015
Posts: 7

View user's profile Send private message

PostPosted: Mon Apr 13, 2015 7:50 pm     Reply with quote

Ok I'll change it, are the other statements correct?? I don't really know how to connect PIN B4(CCP) to the motor driver, I've already search for the data sheet but it's not so clear.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 13, 2015 8:17 pm     Reply with quote

Quote:
I don't really know how to connect PIN B4(CCP) to the motor driver.

1. Post a link to the data sheet for the motor driver.

2. Post a schematic of your project.


How to post an image on the CCS forum:
Go to this website: http://postimage.org/
Upload your image. Select family safe. Then click the first button for
"Hotlink to Forum" to get a link to the image.
Then go to the CCS forum and type Ctrl-V to paste the link into a post.

If postimage.org doesn't work in your country, then use Google to find
another free image hosting site for forums.
DiegoCasso



Joined: 12 Apr 2015
Posts: 7

View user's profile Send private message

PostPosted: Mon Apr 13, 2015 8:41 pm     Reply with quote

http://pdf.datasheetcatalog.com/datasheet/sanyo/ds_pdf_e/LB1649.pdf

This is the data sheet URL
DiegoCasso



Joined: 12 Apr 2015
Posts: 7

View user's profile Send private message

PostPosted: Mon Apr 13, 2015 8:53 pm     Reply with quote

I cannot post the schematic of my project :/ the driver I'm using, the bluetooth module, and the H21A1 optical sensor are not in the component's list of Proteus.
DiegoCasso



Joined: 12 Apr 2015
Posts: 7

View user's profile Send private message

PostPosted: Mon Apr 13, 2015 8:56 pm     Reply with quote

How can I change this statements to CCS?

Code:

void UARTinit9600 (void)
{

   TXSTA= 0B00100100;       // 0B00100100;         // = 0X22 // TXEN=1, BRGH=1 --> Habilita Transmisión y Bajo Baudaje //
   RCSTA= 0B10010000;         // = 0X90 // SPEN=1, CREN=1 --> Habilita Puerto Serial y Recepción
   SPBRG=  25;            // BRGH=1
   
}

void InterruptsInit(void)
{

   RCIF=0;  // Apagamos la Bandera de Interrupcion // BIT 5 - Registro PIR1
   
}

   void comunicacion_serial()
   {
   CMCON   = 0B00000111;


   //Eliminar posible LATCH o Basura en los Puertos
   PORTB   = 0B00000000; //Configuro el registro LATB     - Se elimina posible basura o latch en el Puerto B

   //FUNCIONES DE INICIALIZACION DE PERIFERICOS
  UARTinit9600();
  InterruptsInit();
   }
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 13, 2015 11:26 pm     Reply with quote

Quote:

How can I change this statements to CCS?

void UARTinit9600 (void)
{

TXSTA= 0B00100100; // 0B00100100; // = 0X22 // TXEN=1, BRGH=1 --> Habilita Transmisión y Bajo Baudaje //
RCSTA= 0B10010000; // = 0X90 // SPEN=1, CREN=1 --> Habilita Puerto Serial y Recepción
SPBRG= 25; // BRGH=1

}

I don't know what your oscillator frequency is. Assuming you're using
the internal oscillator at 4 MHz, then the CCS setup is like this:
Code:

#include <16F628a.h>
#fuses INTRC_IO, NOWDT, PUT, BROWNOUT, NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)



Quote:
set_tris_B(0x00); //Declaramos entradas y salidas en RA

This TRIS setting is incorrect. The 16F628A data sheet says:
Quote:
bits TRISB<2:1> have to be set in order to
configure pins RB2/TX/CK and RB1/RX/DT
as the UART.

This means that TRISB should be set to 0x06.

You don't have to use #fast_io. If you delete the #fast_io line and
delete your set_tris_B() line, then the compiler will automatically
set the correct TRIS for the UART.



Quote:

How can I change this statements to CCS?

void InterruptsInit(void)
{
RCIF=0; // Apagamos la Bandera de Interrupcion // BIT 5 - Registro PIR1
}

I don't think you need this, but if you want to do it, then do it like this:
Code:
clear_interrupt(INT_RDA);



Quote:

How can I change this statements to CCS?

CMCON = 0B00000111;

CCS already does this in the startup code that the compiler inserts
at the beginning of main(). You can see this in the .LST file.


Quote:

How can I change this statements to CCS?

PORTB = 0B00000000; //Configuro el registro LATB - Se elimina

The equivalent CCS code is shown below.
Code:
output_b(0x00);

You are using #fast_io on PortB, so the CCS code will write to PortB only.
It will not change TRISB. The 16F628A does not have a LATB register,
so your comment is not correct.
DiegoCasso



Joined: 12 Apr 2015
Posts: 7

View user's profile Send private message

PostPosted: Tue Apr 14, 2015 11:50 pm     Reply with quote

Man, you really saved my life. Thank you so much for your replies. The USART coding for the bluetooth conection was not done for CCS, a friend of mine code it on MPLAB but I needed to use CCS. So far I think my code will work fine, nevertheless, I'll make a final post of my code.

Thanks a lot.
DiegoCasso



Joined: 12 Apr 2015
Posts: 7

View user's profile Send private message

PostPosted: Wed Apr 15, 2015 12:08 am     Reply with quote

I compiled and I only got some errors here:
Code:

static void interrupt isr(void){   //Funcion para interrupcion por recepcion de la usart // Interrupt Service Routines
   if(kbhit()==1){               //Se cumple si entra un dato por el pin receptor de la USART

   Dato=getc();         //Si llega un dato guardalo en el registro Dato
   }
}
jeremiah



Joined: 20 Jul 2010
Posts: 1354

View user's profile Send private message

PostPosted: Wed Apr 15, 2015 7:48 am     Reply with quote

DiegoCasso wrote:
I compiled and I only got some errors here:
Code:

static void interrupt isr(void){   //Funcion para interrupcion por recepcion de la usart // Interrupt Service Routines
   if(kbhit()==1){               //Se cumple si entra un dato por el pin receptor de la USART

   Dato=getc();         //Si llega un dato guardalo en el registro Dato
   }
}


Look at #int_rda in the compiler manual
dyeatman



Joined: 06 Sep 2003
Posts: 1934
Location: Norman, OK

View user's profile Send private message

PostPosted: Wed Apr 15, 2015 11:25 am     Reply with quote

Also, you don't need Kbhit() in an interrupt.
You would not be there unless an interrupt already already occurred.
The word interrupt standalone is not valid in CCS so I put an underscore to tie it to isr.
Static is also not needed.
Code:

void interrupt_isr(void){   //Funcion para interrupcion por recepcion de la usart // Interrupt Service Routines
   Dato=getc();         //Si llega un dato guardalo en el registro Dato
   // add a flag here to indicate you have data
}

_________________
Google and Forum Search are some of your best tools!!!!
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