Sine Data Generation Using Arduino Due

22
ARDUINO DUE BOARD

description

Sine Data Generation Using for Arduino Due: This is the best for you with full code of Sine Data Generation using for Arduino Due by Robomart. https://www.robomart.com/buy-arduino-due-india-price

Transcript of Sine Data Generation Using Arduino Due

Page 2: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

Since real-time calculation is CPU demanding, a sine data array is required for better performanceuint32_t sin768[] PROGMEM= ....while x=[0:5375]; y = 127+127*(sin(2*pi/5376/*or some # you prefer depends on requirement*/))

Step 1: Generate Sine Data Array

Page 3: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

Arduino Due have limited reference. However in order to generate 3 phase sine wave based on Arduino Uno, 1st of all, performance is not applausable due to its low MCLK (16MHz while Due is 84MHz), 2nd, it's limited GPIO can produce max 2 phase output and you need additional analogue circuit to produce the 3rd phase (C=-A-B).Following GPIO enabling was mostly based on try and trial+not helpful datasheet of SAM3X

Step 2: Enabling Parallel Output

Page 4: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

PIOC->PIO_PER = 0xFFFFFFFE; //PIO controller PIO Enable register (refer to p656 of ATMEL SAM3X datasheet) and Arduino Due pin 33-41 and 44-51 were enabledPIOC->PIO_OER = 0xFFFFFFFE; //PIO controller output enable register, refer to p657 of ATMEL SAM3X datasheet PIOC->PIO_OSR = 0xFFFFFFFE; //PIO controller output status register, refer to p658 of ATMEL SAM3X datasheet

Step 2: Enabling Parallel Output

Page 5: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

PIOC->PIO_OWER = 0xFFFFFFFE; //PIO output write enable register, refer to p670 of ATMEL SAM3X datasheet//PIOA->PIO_PDR = 0x30000000; //optional as insurance, does not seem to affect performance, digital pin 10 connect to both PC29 and PA28, digital pin 4 connect to both PC29 and PA28, here to disable disable PIOA #28 & 29

Step 2: Enabling Parallel Output

Page 6: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

To maximize its performance, CPU load should be as low as possible. However due to the non-1to1 correspondence between the CPU pin and the Due pin, bit operation is necessary.

Step 3: Enabling Interrupt

Page 7: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

void TC7_Handler(void){ TC_GetStatus(TC2,1);t = t%samples; //use t%samples instead of 'if' to avoid overflow of tphaseAInc = (preset*t)%5376; //use %5376 to avoid array index overflowphaseBInc = (phaseAInc+1792)%5376;phaseCInc = (phaseAInc+3584)%5376;p_A = sin768[phaseAInc]<<1; //refer to PIOC: PC1 to PC8, corresponding Arduino Due pin: pin 33-40, hence shift left for 1 digit

Step 3: Enabling Interrupt

Page 8: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

p_B = sin768[phaseBInc]<<12; //refer to PIOC: PC12 to PC19, corresponding Arduino Due pin: pin 51-44, hence shift left 12 digitp_C = sin768[phaseCInc]; //phase C output employe PIOC: PC21, PC22, PC23, PC24, PC25,PC26, PC28 and PC29, corresponding Arduino Due pin: digital pin: 9,8,7,6,5,4,3,10, respectively

Step 3: Enabling Interrupt

Page 9: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

p_C2 = (p_C&B11000000)<<22; //this generates PC28 and PC29p_C3 = (p_C&B00111111)<<21; //this generates PC21-PC26p_C = p_C2|p_C3; //this generates parallel output of phase Cp_A = p_A|p_B|p_C; //32 bit output = phase A (8bit)|phase B|phase CPIOC->PIO_ODSR = p_A; //output register =p_At++; }

Step 3: Enabling Interrupt

Page 10: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

build 3x8bit R/2R DAC, loads of ref on google.

Step 4: R/2R DAC

Page 11: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

#define _BV(x) (1<<(x));uint32_t sin768[] PROGMEM= /* x=[0:5375]; y = 127+127*(sin(2*pi/5376)) */uint32_t p_A,p_B,p_C,p_C2,p_C3; //phase A phase B phase C value--though output are 8bits only, p_A and p_B value will be operated to generate a new 32 bit value in order to cop with 32bit PIOC output

Step 5: Full Code

Page 12: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

uint16_t phaseAInc, phaseBInc,phaseCInc,freq, freqNew; uint32_t interval; uint16_t samples,preset; uint32_t t = 0;void setup() {//parallel output PIOC setup: Arduino Due pin33-40 are employed as phase A output while pin 44-51 work for phase B output

Step 5: Full Code

Page 13: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

PIOC->PIO_PER = 0xFFFFFFFE; //PIO controller PIO Enable register (refer to p656 of ATMEL SAM3X datasheet) Arduino Due pin 33-41 and 44-51 were enabledPIOC->PIO_OER = 0xFFFFFFFE; //PIO controller output enable register, refer to p657 of ATMEL SAM3X datasheetPIOC->PIO_OSR = 0xFFFFFFFE; //PIO controller output status register, refer to p658 of ATMEL SAM3X datasheet

Step 5: Full Code

Page 14: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

PIOC->PIO_OWER = 0xFFFFFFFE; //PIO output write enable register, refer to p670 of ATMEL SAM3X datasheet//PIOA->PIO_PDR = 0x30000000; //optional as insurance, does not seem to affect performance, digital pin 10 connect to both PC29 and PA28, digital pin 4 connect to both PC29 and PA28, here to disable disable PIOA #28 & 29 //timer setuppmc_set_writeprotect(false); // disable write protection of Power Management Control registers

Step 5: Full Code

Page 15: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

pmc_enable_periph_clk(ID_TC7); // enable peripheral clock time counter 7TC_Configure(/* clock */TC2,/* channel */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); //TC clock 42MHz (clock, channel, compare mode setting) TC_SetRC(TC2, 1, interval); TC_Start(TC2, 1);// enable timer interrupts on the timer TC2->TC_CHANNEL[1].TC_IER=TC_IER_CPCS; // IER = interrupt enable register TC2->TC_CHANNEL[1].TC_IDR=~TC_IER_CPCS; // IDR = interrupt disable register

Step 5: Full Code

Page 16: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

NVIC_EnableIRQ(TC7_IRQn); // Enable the interrupt in the nested vector interrupt controller freq = 60; //initialize frequency as 60Hz preset = 21; //array index increase by 21 samples = 256; //output samples 256/cycle interval = 42000000/(freq*samples); //interrupt counts TC_SetRC(TC2, 1, interval); //start TC Serial.begin(9600); //for test purpose }

Step 5: Full Code

Page 17: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

void checkFreq(){ freqNew = 20000 ;if (freq == freqNew) {} else{ freq = freqNew;if (freq>20000) {freq = 20000; /*max frequency 20kHz*/};if (freq<1) {freq = 1; /*min frequency 1Hz*/};if (freq>999) {preset = 384; samples = 14;} //for frequency >=1kHz, 14 samples for each cycle

Step 5: Full Code

Page 18: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

else if (freq>499) {preset = 84; samples = 64;} //for 500<=frequency<1000Hz, 64 samples for each cycle else if (freq>99) {preset = 42; samples = 128;} //for 100Hz<=frequency<500Hz, 128 samples/cycleelse {preset = 21; samples = 256;}; //for frequency<100hz, 256 samples for each cycleinterval = 42000000/(freq*samples); t = 0; TC_SetRC(TC2, 1, interval); } }

Step 5: Full Code

Page 19: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

void loop() {checkFreq(); delay(100); }void TC7_Handler(void){ TC_GetStatus(TC2,1);t = t%samples; //use t%samples to avoild overflow of t phaseAInc = (preset*t)%5376; //use %5376 to avoid array index overflowphaseBInc = (phaseAInc+1792)%5376;phaseCInc = (phaseAInc+3584)%5376;

Step 5: Full Code

Page 20: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

p_A = sin768[phaseAInc]<<1; //refer to PIOC: PC1 to PC8, corresponding Arduino Due pin: pin 33-40, hence shift left for 1 digitp_B = sin768[phaseBInc]<<12; //refer to PIOC: PC12 to PC19, corresponding Arduino Due pin: pin 51-44, hence shift left 12 digitp_C = sin768[phaseCInc]; //phase C output employe PIOC: PC21, PC22, PC23, PC24, PC25,PC26, PC28 and PC29, corresponding Arduino Due pin: digital pin: 9,8,7,6,5,4,3,10, respectively

Step 5: Full Code

Page 21: Sine Data Generation Using Arduino Due

Sine Data Generation Using for Arduino Due

p_C2 = (p_C&B11000000)<<22; //this generates PC28 and PC29p_C3 = (p_C&B00111111)<<21; //this generates PC21-PC26 //Serial.println(p_C3,BIN); p_C = p_C2|p_C3; //this generates parallel output of phase Cp_A = p_A|p_B|p_C; //32 bit output = phase A (8bit)|phase B|phase C //Serial.println(p_A>>21,BIN); //PIOC->PIO_ODSR = 0x37E00000;PIOC->PIO_ODSR = p_A; //output register =p_A t++; }

Step 5: Full Code

Page 22: Sine Data Generation Using Arduino Due

THANK YOU