Arduino DUE PWM and ADC

Please help! I am currently looking to control a motor using an Arduino DUE. To do this, I need to perform current sensing. Here is the program I used as a reference. This program also interrupts at the top of the triangle wave.

In this program, which pin on the Arduino DUE should I input the current sensor output voltage?
Also, how can I check the AD converted value on the serial monitor?

Thank you very much.


int Iu_ad;
int Iv_ad;
int Iw_ad;


void pwm3_setup(){
    uint16_t CounterPeriod;
    uint16_t DeadTime;

  
    CounterPeriod = 4200 - 1;
    DeadTime = 100;

    //PWM Power ON
    REG_PMC_PCER1=PMC_PCER1_PID36;

   //Set the carrier frequency
    //use PWM1~3 as 3-phase PWM, PWM0 is for PWM synchronous AD conversion
    REG_PWM_CPRD0 = CounterPeriod;
    REG_PWM_CPRD1 = CounterPeriod;
    REG_PWM_CPRD2 = CounterPeriod;
    REG_PWM_CPRD3 = CounterPeriod;

   //Setting the duty command for each phase
    REG_PWM_CDTY1 = 2100;
    REG_PWM_CDTY2 = 2100;
    REG_PWM_CDTY3 = 2100;

  //Enable dead time, prescaler = 0, triangle wave setting
    REG_PWM_CMR0 = PWM_CMR_CALG | PWM_CMR_CPRE_MCK;
    REG_PWM_CMR1 = PWM_CMR_DTE | PWM_CMR_CALG | PWM_CMR_CPRE_MCK;
    REG_PWM_CMR2 = PWM_CMR_DTE | PWM_CMR_CALG | PWM_CMR_CPRE_MCK;
    REG_PWM_CMR3 = PWM_CMR_DTE | PWM_CMR_CALG | PWM_CMR_CPRE_MCK;

  //Setting the dead time for PWMH and PWML
    REG_PWM_DT1 = PWM_DT_DTH(DeadTime) | PWM_DT_DTL(DeadTime);
    REG_PWM_DT2 = PWM_DT_DTH(DeadTime) | PWM_DT_DTL(DeadTime);
    REG_PWM_DT3 = PWM_DT_DTH(DeadTime) | PWM_DT_DTL(DeadTime);

    
    REG_PIOC_PDR = PIO_PDR_P9 | PIO_PDR_P8 | PIO_PDR_P7 | PIO_PDR_P6 | PIO_PDR_P5 | PIO_PDR_P4;
    
    REG_PIOC_ABSR |= PIO_ABSR_P9 | PIO_ABSR_P8 | PIO_ABSR_P7 | PIO_ABSR_P6 | PIO_ABSR_P5 | PIO_ABSR_P4;

    //PWM event line settings for AD conversion                                                             
    PWM->PWM_CMP[0].PWM_CMPM = PWM_CMPM_CEN;                     
    PWM->PWM_ELMR[1] = PWM_ELMR_CSEL0;                           
    PWM->PWM_CMP[0].PWM_CMPV = PWM_CMPV_CV(CounterPeriod - 10);  

  
    REG_PWM_ENA = PWM_ENA_CHID3 | PWM_ENA_CHID2 | PWM_ENA_CHID1 | PWM_ENA_CHID0;
}

void adc_setup() {
  PMC->PMC_PCER1 |= PMC_PCER1_PID37;                    // ADC power on

  ADC->ADC_CR = ADC_CR_SWRST;                           // Reset ADC
  ADC->ADC_MR =  ADC_MR_TRGEN_EN                       // Hardware trigger select
                  | ADC_MR_TRGSEL_ADC_TRIG5            // Trigger by PWM Event Line 1 
                  | ADC_MR_PRESCAL(1);              

  ADC->ADC_IER = ADC_IER_EOC7;                          // End Of Conversion interrupt enable for channel 7
  NVIC_EnableIRQ(ADC_IRQn);                             // Enable ADC interrupt
  ADC->ADC_CHER = ADC_CHER_CH7 | ADC_CHER_CH6 | ADC_CHER_CH5;  // Enable Channel 5~7
}

int main (void){
  
}
;

void loop(){
  
};



void ADC_Handler() {

 
  Iu_ad = ADC->ADC_CDR[7];  // Read and clear status register 


  Iv_ad = ADC->ADC_CDR[6];
  Iw_ad = ADC->ADC_CDR[5];

  PIOB->PIO_ODSR ^= PIO_ODSR_P27; 
}

I am having a hard time following your question. Please post a schematic, not a frizzy thing. Also post links to the hardware devices you are using showing technical information.

1. Connect the voltage (that is proportional to your current) at APin-A0 of DUE.
2. Connect 1/2 of 5V (2.5V) at APin-A1 as test voltage.
3. Upload the following sketch and check that Serial Monitor shows about 2.5V at 1-sec interval.

void setup() 
{
  Serial.begin(9600);//default Vref = 3.3V
}

void loop() 
{
  unsigned int x = analogRead(A1); //10-bit resolution 
  float Vin = (3.3/1023)*x;
  Serial.println(Vin, 2);
  //-----------------------
  delay(1000);
}

Generation of PWM Signals
Dpin-2 to DPin-13 of DUE delivers 1000 Hz PWM signal when the following instruction is executed:

analogWrite(DPin, byte onPeriod);

Sorry, below is a link to the Arduino DUE microcontroller I am using.

Thanks for the reply. I would like to configure the Arduino DUE microcontroller SAM3X8E to perform current sensing at a sampling frequency of 5Khz.

I saw the data sheet, I cannot see what you have assembled, that is why I asked for a schematic.

The one I am trying to make is not yet finished. So it is very difficult to represent it in a circuit diagram.
However, my plan is to pass the current to a current sensor such as a hall sensor, and input the output voltage to the Arduino DUE, and use the ADC as an overflow interrupt.

You plan a project at the start - not at the end! And I'd suggest you start at the hardware end so you have an IDEA of the signals with which you will be dealing.

Writing code first is a design process programmers call GIGO.

Here are some ideas

1 Like

I would like to know how to perform AD conversion using Arduino DUE before controlling the motor.
In the past, I used the following program to input the output of the current sensor to the Arduino DUE, and then calculated it using an equation that takes into account the characteristics of the current sensor, and displayed it on the serial monitor.

However, this method was limited to AD conversion in 1.2msec, so I wanted to set the register and perform AD conversion with overflow interrupt. I would like to know how to set up for this, or how to enable event interrupt and perform overflow interrupt.

#include <DueTimer.h>

const int VOL_PIN = A8;

int i=0 ;
double average = 0 ;
double average1 = 0 ;
   


void Timer3_handler(void){
    
    
    i++;
    
    analogReadResolution(12);
    
    float value;
    float volt;
    float current;
    
    value = analogRead( VOL_PIN );

    volt = value * (3.3/ 4095.0) ;
    //volt = value * (0.001221) ;
    
    //current = (volt - 2.5)*(25/0.625) ;
    current = (((volt - 2.5)*40) - average) ;

    if (314>=i && i>=300){
      average += current;

    if (i==314){
      average1 = (average / 14) ;
      //Serial.println(average1);
       
    }
    }
    
    //Serial.print( value );
   // Serial.print( "," );
    //Serial.println( volt ); 
    //Serial.print( "," );
    Serial.println( current ); //
}

void setup(){
Serial.begin( 9600 );
Timer3.attachInterrupt(Timer3_handler).start(1200); //(200μS)
}

void loop(){
  
}



/*
void loop(){
    int value;
    float volt;
    float current;
    

    value = analogRead( VOL_PIN );

    volt = value * 5.0 / 4095.0 ;

    current = (volt - 2.5)*(25/2.125) ;
    

    /*Serial.print( " Value:" );
    Serial.print( value );
    
    Serial.print( volt ); 
    Serial.print( "," );
    Serial.println( current );
}*/

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.