Helpful ReplyHot!change adc read from ch0 to all channels

Author
Daniel1990
New Member
  • Total Posts : 11
  • Reward points : 0
  • Joined: 2016/05/22 03:23:28
  • Location: Salzburg
  • Status: online
2017/05/25 10:59:39 (permalink)
0

change adc read from ch0 to all channels

Hello,
i want to change the adc read in the an1160 for the dspic33ep64mc504. They use only ch0->buf0 to measure the bemf. I wanna use ch0(for pot),ch1ch2,ch3 to sample the bemf. I tried to change it (like in the an1160 src for the dspic33fj16mc102), i think i made it correct, but it does not work. The start up is ok, and it works with MINDUTYCYCLE, if i increase the duty cycle with the pot, only the PWM is changing. The motor keeps the rpm and only the current increases. Does anyone know where my problem is?
I would like use all buffers because if i use only CH0 i have to enter BEMF_VDDMAX,  and i have a batterie where BEMF_VDDMAX changes.
 
 
Here are a few codes:
old code :

if(Flags.PreCommutationState == 0) {

  MotorPhaseA = MotorPhaseAState[ADCCommState];
  MotorPhaseB = MotorPhaseBState[ADCCommState];
  MotorPhaseC = MotorPhaseCState[ADCCommState];

  if(MotorPhaseA == 1)
   MotorPhaseA = ADC1BUF0;
  else if(MotorPhaseB == 1)
   MotorPhaseB = ADC1BUF0;
  else if(MotorPhaseC == 1)
   MotorPhaseC = ADC1BUF0;


  MotorNeutralVoltage = (MotorPhaseA + MotorPhaseB + MotorPhaseC) / 3;

 
 
 
new code: here i changed the motorphases to the buffers 1,2,3
 
if(Flags.PreCommutationState == 0) {          
  #ifdef OPEN_LOOP_CONTROL
   DesiredDuty = (unsigned int)(( (unsigned long)ADC1BUF0 * (MAX_DUTY_CYCLE-MIN_DUTY_CYCLE) ) >> 10 ) + MIN_DUTY_CYCLE;
   #else
   DesiredRPM = (unsigned int)(( (unsigned long)ADC1BUF0 * (MAX_RPM-STARTUP_RPM) ) >> 10 ) + STARTUP_RPM;
   #endif
  
   MotorPhaseA = ADC1BUF1;
   MotorPhaseB = ADC1BUF2;
   MotorPhaseC = ADC1BUF3;

 
 
 
in every funktions i deactivated the AD1CH0 channel switch.

    void __attribute__((__interrupt__,auto_psv)) _T1Interrupt(void)
{
    adcBackEMFFilter = 0;
    BlankingCounter = 0;

    if (++ADCCommState > 5)
        ADCCommState = 0;

    //AD1CHS0 = ADC_CHANNEL[ADCCommState];    //switch adc channel
    //switch sector
    IOCON1 = PWM_STATE1[ADCCommState];
    IOCON2 = PWM_STATE2[ADCCommState];
    IOCON3 = PWM_STATE3[ADCCommState];
 

 

void __attribute__((__interrupt__,auto_psv)) _T1Interrupt(void)
{
 adcBackEMFFilter = 0;
    BlankingCounter = 0;

     
    if (++ADCCommState > 5)
        ADCCommState = 0;

 //AD1CHS0 = ADC_CHANNEL[ADCCommState]; //switch adc channel
    //switch sector
 IOCON1 = PWM_STATE1[ADCCommState];
 IOCON2 = PWM_STATE2[ADCCommState];
 IOCON3 = PWM_STATE3[ADCCommState];

 

void Start_Motor()
{
 if(Flags.nb_delay_on == 0) { //this is just to test if we're not in a non-blocking delay actually

     if(++ADCCommState>5) // Change The Six-Step Commutation Sector
       ADCCommState = 0;

  AD1CHS0 = ADC_CHANNEL[ADCCommState]; //Change ADC Channel AN Selection

 
and here is the new adc init
//ADC Init
 
 
    ANSELB=0;
    ANSELA=0;
    ANSELC=0;
    
 ANSELCbits.ANSC2 = 1; // for pot
    ANSELAbits.ANSA0 = 1; // For V_M1
    ANSELAbits.ANSA1 = 1; // For V_M2
 ANSELBbits.ANSB0 = 1; // For V_M3

 AD1CON1 = 0x006C; //ADC is off
      //Continue module operation in Idle mode
      //10-bit, 4-channel ADC operation
      //Data Output Format bits Integer (0000 00dd dddd dddd)
      //PWM Special Event Trigger comparator triggered
      //Samples CH0, CH1, CH2, CH3 simultaneously when CHPS<1:0> = 1x
      //Sampling begins immediately after last conversion SAMP bit is auto-set.
 Nop();
 AD1CON1bits.SSRC = 0; //0 for manual, 2 for Timer3, 3 for SEVTCMP

 AD1CON4 = 0x0000; //no dma usage

 AD1CHS123 = 0x0000; //MUX B CH1, CH2, CH3 negative input is VREF-
      //MUX B CH1 positive input is AN0, CH0 positive input is AN1, CH3 positive input is AN2
      //MUX A CH1, CH2, CH3 negative input is VREF-
      //MUX A CH1 positive input is AN0, CH2 positive input is AN1, CH3 positive input is AN2
    
    AD1CHS0 = 0x0008; //MUX B Channel 0 negative input is VREF-
      //MUX B Channel 0 positive input is AN0
      //MUX A Channel 0 negative input is VREF-
      //MUX A Channel 0 positive input is AN8
      

 AD1CSSL = 0x0000; //Skip all ANx channels for input scan

 AD1CON3 = 0x0005; //ADC Clock derived from system clock
      //Autosample time time bits = 0 TAD since PWM is controlling sampling time
      //TAD = 6*TCY, TAD approx 85 nSec

 AD1CON2 = 0x0300; //ADREF+ = AVDD ADREF- = AVSS
      //Do not scan inputs
      //11 = Converts CH1,CH2,CH3
      //A/D is currently filling buffer 0x0-0x7
      //Interrupts at the completion of conversion for each sample/convert sequence
      //Always starts filling buffer from the beginning
      //Always uses channel input selects for Sample A

 AD1CON1bits.DONE = 0; //Making sure that there is not any conversion in progress
 IPC3bits.AD1IP = 5; //Assigning ADC ISR priority
 IFS0bits.AD1IF = 0; //Clearing the ADC Interrupt Flag
 IEC0bits.AD1IE = 1; //Enabling the ADC conversion complete interrupt
 AD1CON1bits.ADON = 0; //Enabling the ADC module

 
best regards
daniel
 
 
 
#1
Daniel1990
New Member
  • Total Posts : 11
  • Reward points : 0
  • Joined: 2016/05/22 03:23:28
  • Location: Salzburg
  • Status: online
Re: change adc read from ch0 to all channels 2017/07/16 03:33:22 (permalink)
0
Any advice and ideas will be greatly appreciated and would help very much.
 
 
#2
CinziaG
rome burns :D
  • Total Posts : 2657
  • Reward points : 0
  • Joined: 2016/12/07 14:20:36
  • Location: Wien
  • Status: online
Re: change adc read from ch0 to all channels 2017/07/16 04:32:37 (permalink) ☄ Helpfulby Daniel1990 2017/07/24 11:19:41
0
Mmmmm, AN0 is RA0, AN1 is RA1, AN2 is RB0 and AN3 is RB2, according to the docs: this is what your ADC will convert as you write those numbers to AD1CHS0...
 
but now I see an array
ADC_CHANNEL
that is possibly translating numbers for you (I don't like capitals letters for variables :) )

Check if there's something wrong in there, and then all those pins' settings.
#3
Daniel1990
New Member
  • Total Posts : 11
  • Reward points : 0
  • Joined: 2016/05/22 03:23:28
  • Location: Salzburg
  • Status: online
Re: change adc read from ch0 to all channels 2017/07/17 02:47:42 (permalink)
3 (1)
Hi,
 
Thank you for your answer, i checked this but i saw i made a mistake in a post.
 
I deactivated the AD1CHS0 in the function "void Start_Motor()" and the array "ADC_CHANNEL" does not exist anymore, because AD1CHS0 is set to the pot in the ADC init.
 
Futher the AD1CHS0 was used to sample all three phases alternately therefore the array.
 
-> //AD1CHS0 = ADC_CHANNEL[ADCCommState]; //Change ADC Channel AN Selection
 
AD1CHS0 = 0x0008; //MUX B Channel 0 negative input is VREF-
      //MUX B Channel 0 positive input is AN0
      //MUX A Channel 0 negative input is VREF-
      //MUX A Channel 0 positive input is AN8

 
 
AN0(RA0), AN1(RA1), AN2(RB0) should be connected to AD1CH123.

 AD1CHS123 = 0x0000; //MUX B CH1, CH2, CH3 negative input is VREF-
      //MUX B CH1 positive input is AN0, CH0 positive input is AN1, CH3 positive input is AN2
      //MUX A CH1, CH2, CH3 negative input is VREF-
      //MUX A CH1 positive input is AN0, CH2 positive input is AN1, CH3 positive input is AN2

 
Do you have any other ideas what i could check?
#4
Daniel1990
New Member
  • Total Posts : 11
  • Reward points : 0
  • Joined: 2016/05/22 03:23:28
  • Location: Salzburg
  • Status: online
Re: change adc read from ch0 to all channels 2017/08/16 04:01:12 (permalink)
3 (1)
Hey Cinzia,
still some questions, maybe you can help me
 
I tried it, it works better when I change the PTPER or increase the pwm frequency from 20kHz to 40kHz.


In the AN1160 the PTPER is calculated as followed:
PTPER =2*(FCY / (FPWM))-1      ->           6999=2*(70MHz/20kHz)-1

I read in the dspic33e family reference guide that PTPER is as calculated as followed:
PTPER = FCY / FPWM – 1             ->           3499=70MHz/20KHz-1
 
Why is the PTPER multiple with 2 in the AN1160?
It works far better when I change the PTPER to “PTPER = FCY / FPWM – 1” but why does that effect the adc read?

Is there something I have to calculate new in the pwm module when I use 4 adc channels instead of one? The adc is triggered by the SEVT.

Or could it depend on the pwm resolution?
 
 
 
1)         SEVT – Special Event Trigger

I know what the SEVT is, but i don’t know where the TRIGGER_VECTOR numbers come from.
How can i calculate them?

-> SEVTCMP = trigger_time[trigger_count]; -> unsigned int trigger_time[35] = TRIGGER_VECTOR;
TRIGGER_VECTOR={20,400,800,1200,1600,2000,2400,2800,3200,3600,4000,4400,4800,5200,5600,6000,6400,6800,7200,7600,8000,8400,8800,9200,9600,10000,10400,10800,11200,11600,12000,12400,12800,13200,13600}
unsigned int trigger_count;
unsigned int trigger_time[35] = TRIGGER_VECTOR;
if(++trigger_count > (ADC_READS_PER_PWM_PERIOD-1))
             trigger_count = 0;
 
             SEVTCMP = trigger_time[trigger_count];
if(trigger_count < ADC_READS_PER_PWM_PERIOD-1)
             if(trigger_time[trigger_count+1] > PDC1) {
             SEVTCMP = trigger_time[0];
             trigger_count = 0;
             }
This is inside the code:
/*
                               Here we will set the next triggering moment for the special
                event compare trigger existing in the PWM module. The next triggering
                moment is found in the trigger_time vector (defined in defs.c), and
                it should be calculated by the programmer to match the number of ADC
                reads for every PWM period.
                               For more information on this, please see dsPIC's datasheet.    
                */
 
But i found nothing in the datasheet.
 
 
 
2)            PWM
I saw there are different pwm operating modes available.
-> Push-Pull Output mode
-> Complementary Output mode
-> Redundant Output mode
-> Independent Output mode
 
And I saw that the pwm module can operate in either the standard edge-aligned or center-aligned time base.

For which application should i use which mode? On what does it depend on?
Which is recommended for brushless dc motor control? (six step trapezoidal)
 
 
Thank you
#5
CinziaG
rome burns :D
  • Total Posts : 2657
  • Reward points : 0
  • Joined: 2016/12/07 14:20:36
  • Location: Wien
  • Status: online
Re: change adc read from ch0 to all channels 2017/08/16 05:02:18 (permalink)
0
I am not sure about this all... sorry
#6
Daniel1990
New Member
  • Total Posts : 11
  • Reward points : 0
  • Joined: 2016/05/22 03:23:28
  • Location: Salzburg
  • Status: online
Re: change adc read from ch0 to all channels 2017/08/16 06:59:47 (permalink)
3 (1)
ok, thanks anyway. I will keep trying :)
#7
Jump to:
© 2017 APG vNext Commercial Version 4.5