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 support@ccsinfo.com

warnings for usart and adc

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



Joined: 22 Sep 2016
Posts: 1

View user's profile Send private message

warnings for usart and adc
PostPosted: Thu Sep 22, 2016 10:28 pm     Reply with quote

Hello I am new to the site, I found some references to these problems but fails to get it right, my code is as follows:

Code:

#include <16F886.h>
#device ADC=10   
#include <math.h>
#FUSES HS,NOPROTECT,NOWDT,NOBROWNOUT,NOPUT,NOLVP,NOMCLR,NOCPD, NOWRT, NODEBUG
#USE delay(clock=20000000)
#use rs232(uart1,baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8, parity=n)
#include <stdlib.h>
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#define stby PIN_B1
int16 lect[10];
int16 sen[10];
int16 calib=512;
int8  pos,i;
int16 num,den;
int16  setpoint=45;
signed int16  error,erroracum,errorinst,errorpas;
float  kp=1;
float  ki=1;
float  kd=1;
signed int16  salida_pwm;
signed int16  speedmaxder;
signed int16  speedmaxizq;
signed int16  speedmedder;
signed int16  speedmedizq;
signed int16  motorder;
signed int16  motorizq;
int1  flag1=0, flag2=0;
int8  k=0;
char cadena[4];               
char caracter;
#int_rda
void RDA_isr()
{
printf("1");
   if(flag1==0)
   {     
      caracter=getc();
      if(caracter=='1')
      {
         printf("2");
         flag1=1;
         flag2=1;
         output_low(stby);
         i=0;
         k=0;
         printf("\fkp:%01.1f \n\rki:%01.1f \n\rkd:%01.1f",kp,ki,kd);
         delay_ms(2000);
         printf("\f");
      }
   }
   if(flag2==1)
   {
      if(k==0)//valor de kp
      {
         cadena[i]=getc();             //Recepción del string         
         ++i;                          //Preparación para recibir el siguiente caracter
         if (i==4)
         {                   //Todos los caracteres recibidos
            i=0;                       //Preparación para recibir el siguiente string
            kp = atof(cadena);      //Paso del string a su valor float           
            printf("\fnuevo kp:%01.1f",kp);
            delay_ms(2000);
            printf("\f");
            k++;
         }
      }
      if(k==1)//valor de ki
      {
         cadena[i]=getc();             //Recepción del string         
         ++i;                          //Preparación para recibir el siguiente caracter
         if (i==4)
         {                   //Todos los caracteres recibidos
            i=0;                       //Preparación para recibir el siguiente string
            ki = atof(cadena);      //Paso del string a su valor float
            printf("\fnuevo ki:%01.1f",ki);
            delay_ms(2000);
            printf("\f");
            k++;
         }
      }
      if(k==2)//valor de kd
      {
         cadena[i]=getc();             //Recepción del string         
         ++i;                          //Preparación para recibir el siguiente caracter
         if (i==4)
         {                   //Todos los caracteres recibidos
            i=0;                       //Preparación para recibir el siguiente string
            kd = atof(cadena);      //Paso del string a su valor float
            printf("\fnuevo kp:%01.1f\n\rnuevo ki:%01.1f\n\rnuevo kd:%01.1f",kp,ki,kd);
            delay_ms(2000);
            printf("\f");
            k++;
            flag1=0;
            flag2=0;
            output_high(stby);
         }
      }
   }
}
void lectura()
{
   for(i=0;i<=9;i++)
      {
         if(i>4)
         {
            if(i==5)
            {
               set_adc_channel(13);
               delay_us(10);
               lect[5]=read_adc();   
            }
            if(i==6)
            {
               set_adc_channel(11);
               delay_us(10);
               lect[6]=read_adc();   
            }
            if(i==7)
            {
               set_adc_channel(9);
               delay_us(10);
               lect[7]=read_adc();   
            }
            if(i==8)
            {
               set_adc_channel(8);
               delay_us(10);
               lect[8]=read_adc();   
            }
            if(i==9)
            {
               set_adc_channel(12);
               delay_us(10);
               lect[9]=read_adc();   
            }
         }
         else
         {
            set_adc_channel(i);
            delay_us(10);
            lect[i]=read_adc();
         }
      }   
}
void calibracion()
{
   for(i=0;i<=9;i++)
   {
      if(lect[i]<calib)
      {
         sen[i]=0;   
      }
      else
      {
         sen[i]=10;
      }
   }
   num=0*sen[0]+10*sen[1]+20*sen[2]+30*sen[3]+40*sen[4]+50*sen[5]+60*sen[6]+70*sen[7]+80*sen[8]+90*sen[9];
   den=sen[0]+sen[1]+sen[2]+sen[3]+sen[4]+sen[5]+sen[6]+sen[7]+sen[8]+sen[9];
   pos=num/den;
}
void motores(signed int16 motor_izq, signed int16 motor_der)
{
    set_pwm1_duty(motor_izq);//motor izquierdo
    set_pwm2_duty(motor_der);//motor derecho
}
void pid()
{
  error     = pos - setpoint;
  erroracum = erroracum + errorpas;
  errorinst = error - errorpas;
  salida_pwm= ceil((error*Kp)+(errorinst*Kd)+(erroracum*Ki));
  errorpas = error;
  if (salida_pwm > speedmedder) 
  {
    salida_pwm = speedmedder;
  }
  if (salida_pwm < -speedmedizq) 
  {
   
    salida_pwm = -speedmedizq;
  }
  if (salida_pwm > 0)
  {
    motorder=speedmedder-salida_pwm;
    motores(speedmedizq,motorder);
  }
  if (salida_pwm <0)
  {
      motorizq=speedmedizq+salida_pwm;
      motores(motorizq,speedmedder);
  }   
}
void main (void)
{
   setup_adc_ports(all_analog);
   setup_adc(adc_clock_internal);   
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(t1_disabled);
   setup_timer_2(t2_div_by_16,255,16);
   setup_ccp1(ccp_pwm);//motor izquierdo
   setup_ccp2(ccp_pwm);//motor derecho
   setup_spi(false);
   enable_interrupts(global);
   enable_interrupts(int_rda);
   errorpas=0;
   erroracum=0;
   errorinst=0;
   speedmaxder=1000;
   speedmaxizq=1000;
   speedmedder=speedmaxder*0.5;
   speedmedizq=speedmaxizq*0.5;
   printf("\fconexion establecida");
   output_high(stby);
 while (true)
 {
     lectura();
     calibracion();
     pid();
 }
}



This code is used with a bluetooth, I check the syntax and I'm sure it's okay, I guess that's the warnings I can not understand they mean and how to fix it.

the warnings:
Code:

Warning 216 "code.c" Line 224(1,2):Interrupts disabled during call to prevent re-entrancy: [@MULFF]
Warning 216 "code.c" Line 224(1,2):Interrupts disabled during call to prevent re-entrancy: [@ADDFF]
Warning 216 "code.c" Line 224(1,2):Interrupts disabled during call to prevent re-entrancy: [@ITOF]
Ttelmah



Joined: 11 Mar 2010
Posts: 19447

View user's profile Send private message

PostPosted: Fri Sep 23, 2016 1:38 am     Reply with quote

You are doing far too much inside the interrupt handler. Think about it for a moment. Characters can arrive every 1.04mSec. The hardware gives just under 2 characters of buffering in total, so you must be out of the interrupt in less than 2.08mSec, if data is not to be lost. Now a print like:

"\fkp:%01.1f \n\rki:%01.1f \n\rkd:%01.1f"

Could easily take 50 or more mSec to complete.....

General rule is that an interrupt should just handle the hardware event that it is triggered by, and get out ASAP. Do a search here, and look at the example files. You want something like a basic serial buffer (ex_sisr.c), and then in your main code, to check if a character has arrived, and handle it here.

The actual error is because you are doing maths and printing inside the ISR, which means that you cannot do this in the main code (think about it, there is just one maths routine to do multiply for example - if you were half way through a multiply in the 'main' code, when the interrupt triggered, the values in the external code would get destroyed. To prevent this the compiler ensures that interrupts are disabled when you are inside any routine that is also used in the interrupt.

Now other comments:

Always have the keyword 'ERRORS' in any serial setup, that uses the hardware UART. 'UART1', already specifies which pins to use:

#use rs232(UART1, BAUD=9600, BITS=8, PARITY=n, ERRORS)

Then you really need to rethink your PID. Floating point maths is _slow_. This is why if you look at PID examples on the MicroChip site, they will use scaled integers, not FP for a PID. Now a lot depends on the nature of your PID (things like a heater for example can accept much slower control than a motor), but I'd not be surprised to see the code 'hunting' when trying to hold a speed, as the maths can't correct quickly enough....

A PWM, can't accept a signed value. If you have signed values, for direction control, you need to actually remove the 'sign', set the direction control bits, and then just program the PWM with the unsigned value.
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