Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] problem to keep hold button in matrix keypad dspic30f

Status
Not open for further replies.

freedomhouse

Newbie level 4
Joined
Jun 25, 2014
Messages
5
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
47
hi,

i want use keypad for dicrete variation of dc motor.

my problem is:

when i hold dow button all work good. (pwm change)
when i relase button stop of work.

i did the on-board debbugger with pickit3 and mplab x....all work good button keep hold and pwm keep hold at the new value, but when i flash the dspic all work but button don't keep hold, when i relase i pwm return to 50%value PDC3 variable.
i don't know why because with on board simulation work and when i program/flash the dspic don't work!!!
I also changed the colums port in all portB...but all is like up, isn't a ports problem.

this is my code.

Code:
#include <p30f2010.h>
#include <libpic30.h>
#include "delays.h"


#define Byte unsigned char
#pragma config FOS=FRC                 // Oscillator Source (Internal Fast RC)
#define Byte unsigned char
#define stato_mosfet    LATFbits.LATF3
#define output_mosfet   PORTFbits.RF3
// keypad definitions - LAT for outputs
#define kp_row_1        LATEbits.LATE0
#define kp_row_1_tris   TRISEbits.TRISE0
#define kp_row_2        LATEbits.LATE1
#define kp_row_2_tris   TRISEbits.TRISE1
#define kp_row_3        LATEbits.LATE2
#define kp_row_3_tris   TRISEbits.TRISE2
#define kp_row_4        LATEbits.LATE3
#define kp_row_4_tris   TRISEbits.TRISE3
// keypad definitions - PORT for inputs - be sure to us CNxx pins for input!
#define kp_col_1        PORTCbits.RC13
#define kp_col_1_tris   TRISCbits.TRISC13
#define kp_col_2        PORTCbits.RC14
#define kp_col_2_tris   TRISCbits.TRISC14
#define kp_col_3        PORTDbits.RD1
#define kp_col_3_tris   TRISDbits.TRISD1
#define kp_col_4        PORTFbits.RF2
#define kp_col_4_tris   TRISFbits.TRISF2
int key=0;                    // return value
int saved_key = 0;



int G;        // gradi ogni movimento 360/N
int U;        //tasti inutilizzati
int N;        //numero slot

 int Max_count_giro;                 //n linee contate a giro
 float Risoluzione;                  // risoluzione encoder
 int Pos_misurata;                //posiizione angolare
 int Pos_desiderata;                //posiizione desiderata variata con Vrif
 long Error[10];
 long Accumulator;
 long PID;
 int PTerm;
 int ITerm;
 int DTerm;
 int i;
 Byte Divider;
 int ADCValue;


int keypad(void);
void InitADC(void);
void InitPWM(void);
void InitQEI(void);
void Calcolo_Posizione(void);
void Calcolo_Pos_desiderata(void);
void OverHeat(void);
int main(void);                    // Declare Main Function


int main(void)

{  TRISF=0x0001;
   stato_mosfet=1;//chiudo mosfet
    // Set constants here

   PTerm =2000;
   ITerm =25;
   DTerm = 0;
   Divider =10;
   N=10;
   G=360/N;

   InitADC();
   InitPWM();
   InitQEI();

   /* Set up the Interrupts */



      while(1)
   {


         key=keypad();
         
         if (key!=0)
    {
        saved_key = key;
    }

       Pos_desiderata=saved_key*G*(32767/360);

     

        Pos_misurata=POSCNT*32767/1999;           // misura posizone angolare riportare 1999 linee a numero digitale 16bit-->
                                                   //---> risoluzione*posizione in linee misurata/max_count_giro=POSCNT/32767




         Byte i=0;

    for(i=0;i<10;i++)
    Error[i+1] = Error[i];
    Error[0] = Pos_desiderata-Pos_misurata;


  PID = Error[0]*PTerm;     // start with proportional gain
  Accumulator += Error[0];  // accumulator is sum of errors
  PID += ITerm*Accumulator; // add integral gain and error accumulation
  PID += DTerm*(Error[0]-Error[9]); // differential gain comes next
  PID = PID>>Divider; // scale PID down with divider

  if (Accumulator > 40000)
Accumulator = 40000;

if (Accumulator < -40000)
Accumulator = -40000;

//comment out to speed up PID loop
//Serial.print("PID= ");
//  Serial.println(PID,DEC);

// limit the PID to the resolution we have for the PWM variable

  if(PID>=121)
    PID = 100;
  if(PID<=-121)
    PID =-100;

  PDC3=PID+PTPER;

  OverHeat();

	}
   return 0;
 }

void InitPWM(void)
 {
                                 // ***** CONFIGURE 3 OUTPUT PWM *****
     PTPER = 0x007A;                // 122 Time base register = 126d (=> PDCx Value for 100% Duty Cycle = 254d (2X(PTPER+1)) )


     PDC3 = PTPER;                // PWM1 value = 50%


     //PWMCON1 = 0x0077;            // PMOD3:PMOD1 = 0 (PWM I/O pin pairs are in the complementary output mode)
                                 // PEN3H-PEN1H = 7 (PWM1H..PWM3H pins are enabled for PWM output)
                                 // PEN3L-PEN1L = 7 (PWM1L..PWM3L pins are enabled for PWM output)

     PWMCON1=0x0044;               //complementary mode, only PWM3H & pwm3l as PWM outpur

     PWMCON2 = 0x0004;            // SEVOPS<3:0> = 0 (PWM Special Event Trigger Output Postscale Select bits = 1:1 (Not Used))
                                 // IUE = 1 (Updates to the active PDC registers are immediate)
                                 // OSYNC = 0 (Output overrides via the OVDCON register occur on next TCY boundary)
                                 // UDIS = 0 (Updates from duty cycle and period buffer registers are enabled)

    //PTCON = 0x800C;                // PTEN = 1 (PWM time base is ON)
                                 // PTSIDL = 0 (PWM time base runs in CPU Idle mode)
                                 // PTOPS<3:0> = 0 (PWM Time Base Output Postscale Select bits = 1:1 Postscale)
                                 // PTCKPS<1:0> = 3 (PWM Time Base Input Clock Prescale Select bits => clock period is 64 TCY (1:64 prescale))
                                 // PTMOD<1:0> = 0 (PWM Time Base Mode Select bits => PWM time base operates in a free running mode)

                                 // If internal 7.37 MHz oscillator is used =>
                                 // PWM Frequency = FOSC/(4*PTMRPrescaler*(PTPER+1))
                                 // PWM Frequency = 7.37e6/(4*64*(126+1) = 226.7 Hz

                                 // PWM Duty Cycle [%] = 100*(2*PDCx)/(PTPER+1)
     PTCON=0x8000;              // 1:1prescale PTPER=(FOSC/(4*PTMRRrescaler*PWM Frequency))-1=
                                  // PTPER= (7.37e6/4*1*15e3)-1)=122
     DTCON1= 0x0008;             // deadtime=DTCON1value*Tcy = 2us
 }


void InitADC(void)
{                             // ***** CONFIGURE 3 INPUT ADC *****
     ADPCFG = 0x0030;             // PCFG<15:0>: Analog Input Pin Configuration Control bits
                                 //     1 = Analog input pin in Digital mode, port read input enabled, A/D input multiplexer input connected to AVSS
                                 //     00 = Analog input pin in Analog mode, port read input disabled, A/D samples pin voltage
                                 // RB4..RB5 = digital QEI

     ADCON1 = 0x00EC;             // ADON: A/D Operating Mode bit = 0 (A/D Converter is off)
                                 // ADSIDL : Stop in idle mode bit = 0 (Continue module operation in idle mode)
                                 // FORM<1:0> : Data Output Format bits = 0 (Integer 10 bits)
                                 // SSRC<2:0>: Conversion Trigger Source Select bits = 7 (Internal counter ends sampling and starts conversion (auto convert))
                                 // SIMSAM bit : Simultaneous Sample Select bit = 1 implies ...
                                 //     Samples CH0, CH1, CH2, CH3 simultaneously (when CHPS = 1x)
                                 //     or
                                 //     Samples CH0 and CH1 simultaneously (when CHPS = 01)
                                 // ASAM : A/D Sample Auto-Start bit = 1 (for auto sample after convert)

     ADCON2 = 0xE308;             // VCFG<2:0> : Voltage Reference Configuration Configuration bits = 7 (Reference Voltages = AVdd/AVss)
                                 // CSCNA bit : Scan Input Selections for CH0+ S/H Input for MUX A Input Multiplexer Setting bit = 0 (Do Not Scan inputs)
                                 // CHPS<1:0> : Selects Channels Utilized bits = 1x implies simultaneous ...
                                 //     sample CH0 to CH3
                                 // SMPI<3:0> : Sample/Convert Sequences Per Interrupt Selection bits = 2 for interrupt after 3 converts
                                 // BUFM : Buffer Mode Select bit = 0 (Buffer configured as one 16-word buffer ADCBUF(15...0.))
                                 // ALTS: Alternate Input Sample Mode Select bit = 0 (Always use MUX A input multiplexer settings)

     ADCON3 = 0x0302;             // SAMC<4:0>: Auto-Sample Time bits = 3 (3 Tad)
                                 // ADRC: A/D Conversion Clock Source bit = 0 (Clock derived from system clock)
                                 // ADCS<5:0>: A/D Conversion Clock Select bits = 2 (2 TCY)

     ADCHS = 0x0020;             // CH123NA<1:0>: Channel 1, 2, 3 Negative Input Select for MUX A Multiplexer Setting bits = 0 (CH1, CH2, CH3 negative input is VREF-)
                                 // CH123SA: Channel 1, 2, 3 Positive Input Select for MUX A Multiplexer Setting bit = 1 implies...
                                 //     CH1 = AN3 / CH2 = AN4 / CH3 = AN5
                                 //     ADCBUF1 = AN3 / ADCBUF2 = AN4 / ADCBUF3 = AN5
                                 // CH0NA: Channel 0 Negative Input Select for MUX A Multiplexer Setting bit = 0 (Channel 0 negative input is VREF-)
                                 // CH0SA<3:0>: Channel 0 Positive Input Select for MUX A Multiplexer Setting bits = 0 implies...
                                 //     Connect AN0 as CH0 input => ADCBUF0 = AN0

     ADCSSL = 0;                    // CSSL<15:0>: A/D Input Pin Scan Selection bits
                                 //     1 = Select ANx for input scan
                                 //     0 = Skip ANx for input scan
                                 // ***NOT USED***

     ADCON1bits.ADON = 1;         // turn ADC ON



}



void InitQEI(void)
{

                           /// INITIALIZING THE QEI MODULE
QEICONbits.QEIM = 0;                   // Disable QEI Module
QEICONbits.CNTERR = 0;                 // Clear any count errors
QEICONbits.QEISIDL = 0;                // Continue operation during sleep
QEICONbits.SWPAB = 0;                  // QEA and QEB not swapped
QEICONbits.PCDOUT = 0;                 // Normal I/O pin operation
QEICONbits.POSRES = 1;                  // Index pulse resets position counter   POSRES=0 if QEIM=111 reset by MAXCNT
DFLTCONbits.CEID = 1;                   // Count error interrupts disabled
DFLTCONbits.QEOUT = 1;                  // Digital filters output enabled for QEn pins
DFLTCONbits.QECK = 5;                    // 1:64 clock divide for digital filter for QEn
//DFLTCONbits.INDOUT = 1;                  // Digital filter output enabled for Index pin
//DFLTCONbits.INDCK = 5;                   // 1:64 clock divide for digital filter for Index
POSCNT = 0;                             // Reset position counter
QEICONbits.QEIM = 6;                     // X4 mode with position counter reset by Index or QEIM=111 position reset MAXCNT if 3rd pin encoder INDEX is not present


}



void OverHeat (void)
{
 

  ADCValue=ADCBUF0;

 if(ADCValue>429)                                            //4.5V max input   if T>70°C stoppa alimentazione dspi
 {stato_mosfet=0;}                                     // else if<=50°C riprendi l'alimentazione dspic

 else if(ADCValue<=307)                                 //ADCBUF3 an2
   {stato_mosfet=1;}
}

// read 4x4 keypad
int keypad(void)
{

    kp_row_1_tris = 1;          // rows are outputs
    kp_row_2_tris = 1;          // rows are outputs
    kp_row_3_tris = 1;          // rows are outputs
    kp_row_4_tris = 1;          // rows are outputs
    kp_col_1_tris = 1;          // columns are inputs
    kp_col_2_tris = 1;          // columns are inputs
    kp_col_3_tris = 1;          // columns are inputs
    kp_col_4_tris = 1;          // columns are inputs


    kp_row_1_tris = 0;          // rows are outputs
    kp_row_1 = 0;               // row 1 low to select
    kp_row_2 = 1;
    kp_row_3 = 1;
    kp_row_4 = 1;
	delayms(10);                // allow settle time





    if(!kp_col_1)
    {
        key = 1;
    }
    if(!kp_col_2)
    {
        key = 2;
    }
    if(!kp_col_3)
    {
        key = 3;
    }
    if(!kp_col_4)
    {
        key = 0;
    }

    kp_row_2_tris = 0;          // rows are outputs
    kp_row_1 = 1;
    kp_row_2 = 0;                 // row 2 low to select
    kp_row_3 = 1;
    kp_row_4 = 1;
	delayms(10);                // allow settle time


    if(!kp_col_1)
    {
        key = 4;
    }
    if(!kp_col_2)
    {
        key = 5;
    }
    if(!kp_col_3)
    {
        key = 6;
    }



    kp_row_3_tris = 0;          // rows are outputs
    kp_row_1 = 1;
    kp_row_2 = 1;
    kp_row_3 = 0;                // row 3 low to select
    kp_row_4 = 1;
        delayms(10);                // allow settle time

    if(!kp_col_1)
    {
        key = 7; 
    }
    if(!kp_col_2)
    {
        key = 8;
    }
    if(!kp_col_3)
    {
        key = 9;
    }




    kp_row_4_tris = 0;          // rows are outputs
    kp_row_1 = 1;
    kp_row_2 = 1;
    kp_row_3 = 1;
    kp_row_4 = 0;               // row 4 low to select
	delayms(10);                // allow settle time


    if(!kp_col_2)
    {
        key = 10;
    }



    return key;              // return
}
 

Have you scoped your keypad lines to see that there is no hardware timing problem, like missing pullups/ pulldowns?

The only reason I see is that a new key-value is introduced.
 

the rows outputs scoped with oscilloscope is the same of mplab sim:
input rows por E0..E3.png

the columns are connected at the pins of dspic and a 5V with 100k resistence like this:
keyboardmatrix.png

i scoped its and there is 5V every times

i cancel also saved-.key variable isert because i thinkes tath was a problem of the variable but all is the same,

i don't use pull ups resistence with software.

what is hardware tming problem, i'm no an expert of dspic i used its only for adc converter and pwm generation.


thanks

regards
davide
 

From your drawing and program you use pullups on your output lines, and the input line float. If this is correct, there are no wonder you have intermediate combinations on the input lines, depending on your scan structure.

If you drive your output lines, you don't need pullups on them. But you need pulldowns on the open input lines to define the level when no output drives the line.

If you let the input float, all readings for a time will be active until the charge on the input line goes above the HIGH level threshold, if ever. This mean that you will see a signal on the input for all the lines you scan.

Put the pullups on the input lines, and you will se a difference. 100k may be on the high side, I would have used 22k as a start value. You should keep the 100k on the output lines, since you are floating them in your scan routine.
 
thanks.

i used columns as input and used port B with pullup resistores. nothing pin collegate to 5V.

it works but not properly. i have this problem now:

when i touch oscilloscope ground or touch with fingers the pins of columns or rows and press button it "work" pwm keep hold at new value.
when i relase the touch pwm return to 50%.

i don't now why ..i think is a problem of interference, i used also decoupling capacitance but nothing to do.
but i think now is only an hardware problem.
what i can do for this problem?
i'm using a breadboard with alluminium conductors
 

Can you find out which value the key has when you release all, and it should be 0? What is the idle value of your key? Should be 0, since you use that as a test value for changing the value? How about presetting it to 0 when you start keypad()?
 

hi when relase all key assume the value that i declare in the main key=0 pwm=50%...if i delcare key=-1 it assume pwm<50% (because pos_desiderata<pos_misurata=0)

I noted this:

when I'm in simulation the pwm track on the oscilloscope is always active.
after I flashed the pwm is freezed and when i touch pin secially portb pins it becomes active and work..when i relase it return to initial key value now setted a -1 and track on scope freeza.
is like the dspic stop running and when i touch pin restart to runnging
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top