/************************************************************************** * Programma per la movimentazione di un motore DC Con il modulo aggiuntivo Motore * Non x il GEVINO Motore. * Realizzato da Giorgio Evangelista il 20/06/2019 * * Ingresso 2 Avanti * Ingresso 3 In Dietro * Ingresso 4 Oscilla - swings * Al superamento della corrente di soglia si blocca. * * Impostare la scheda Arduino/Genuino Zero (Native USB Port) * Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) * Sketch -> Include Library -> Manage Libreries -> U8g2 by oliver -> Install *************************************************************************/ #define swings 1 //#define SPI_PIN #define I2C_Serial1_PIN #define PNP_v1_2 #include "gevino_opto_npn_io.h" #ifdef I2C_Serial1_PIN #define ENABLE 0 // enable input of motor driver #define IN1 20 // input-1 of motor driver #define IN2 21 // input-2 of motor driver #else #define ENABLE 23 // enable input of motor driver #define IN1 22 // input-1 of motor driver #define IN2 24 // input-2 of motor driver #endif #define PWM_speed 20000 // in hertz * 100 char Speed; #define Foward() {digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW);} #define Backward() {digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH);} #define Stop() {digitalWrite(IN1, LOW); digitalWrite(IN2, LOW);} // Blocca il motore #define Alt() {Speed =0; digitalWrite(IN1, LOW); digitalWrite(IN2, LOW);} // Disalimenta il motore // Parametri da cambiare #define RampaAvanti 500 // Diminuire per Accelerare #define RampaIndietro 500 // Diminuire per Accelerare #define CorrenteBlocco 1000 // In mA void setup() { SerialUSB.begin(115200); gevino_io_setup(); analogReference(AR_INTERNAL1V0); analogReadResolution(12); pinMode(ENABLE, OUTPUT); pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); SetupTimer(); // Avvio il timer pinMode(A0, INPUT); pinMode(A1, INPUT); SerialUSB.println("Inizio"); } char StopVar = 0; void loop () { if(In2 && !StopVar && !Speed){ Foward(); Speed = 0; for( int i =0; i< 50; i++){ Speed++; delay(RampaAvanti); Read(); } } if(In3 && !StopVar && !Speed){ Backward(); Speed = 0; for( int i =0; i< 50; i++){ Speed++; delay(RampaIndietro); Read(); } } Read(); if( Read() > CorrenteBlocco) StopVar = 1; if(StopVar) Alt(); if( !In2 && !In3 && !In4){ StopVar = 0; Alt(); } if(swings || In4){ // Motore Oscilla Foward(); Speed = 0; for( int i =0; i< 100; i++){ Speed++; delay(5); } for( int i =0; i< 100; i++){ Speed--; delay(5); } Backward(); Speed = 0; for( int i =0; i< 100; i++){ Speed++; delay(5); } for( int i =0; i< 100; i++){ Speed--; delay(5); } Speed = 0; } } int Read(void){ // Legge e fa media delle letture, ritorna mA long Media ; int Current; // Sono milli Amper Media = 0; for(int i = 0; i < 100; i++){ // Leggo il valore analogico 100 volte 96 bit x A #ifdef PNP_v1_2 Media += analogRead(A1); #else Media += analogRead(A0); #endif } Current = (Media/200); SerialUSB.print(Current); SerialUSB.print(" "); SerialUSB.print(StopVar * 1000); SerialUSB.print(" "); SerialUSB.println(1010); // if(millis() - PrintMillis >= 100 ){ // PrintMillis = millis(); // SerialUSB.println(Current); // } return Current; } void TC4_Handler() // Interrupt Service Routine (ISR) for timer TC4 { // Check for overflow (OVF) interrupt if (TC4->COUNT16.INTFLAG.bit.OVF && TC4->COUNT16.INTENSET.bit.OVF) { // PWM static unsigned char pwm; if(++pwm>100) pwm = 0; if ( pwm < Speed ) digitalWrite(ENABLE, HIGH); else digitalWrite(ENABLE, LOW); REG_TC4_INTFLAG = TC_INTFLAG_OVF; // Clear the OVF interrupt flag } } // Set timer TC4 to call the TC4_Handler every second void SetupTimer() { // The code puts timer TC4 into match frequency (MFRQ) mode. In this mode the timer counts up to the value in the CC0 register before overflowing and resetting the timer back to 0. // I've set the generic clock 4 (GCLK4) to 48MHz and the timer prescaler to 1024. Therefore the timer's being clocked at 46.875kHz. // Using the formula: // timer frequency = generic clock frequency / (N * (CC0 + 1)) // where: // N = timer prescaler // CC0 = value in the CC0 register // ...we can calculate CC0 for a timer frequency of 1Hz. // So, // CC0 = (48MHz / 1024) - 1 = 46874 = 0xB71A (hex) // This will cause the timer to overflow every second. // Set up the generic clock (GCLK4) used to clock timers REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) | // Divide the 48MHz clock source by divisor 1: 48MHz/1=48MHz GCLK_GENDIV_ID(4); // Select Generic Clock (GCLK) 4 while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization REG_GCLK_GENCTRL = GCLK_GENCTRL_IDC | // Set the duty cycle to 50/50 HIGH/LOW GCLK_GENCTRL_GENEN | // Enable GCLK4 GCLK_GENCTRL_SRC_DFLL48M | // Set the 48MHz clock source GCLK_GENCTRL_ID(4); // Select GCLK4 while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization // Feed GCLK4 to TC4 and TC5 REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | // Enable GCLK4 to TC4 and TC5 GCLK_CLKCTRL_GEN_GCLK4 | // Select GCLK4 GCLK_CLKCTRL_ID_TC4_TC5; // Feed the GCLK4 to TC4 and TC5 while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization REG_TC4_COUNT16_CC0 = 0xB71A / PWM_speed; // Set the TC4 CC0 register as the TOP value in match frequency mode (1 secondo) while (TC4->COUNT16.STATUS.bit.SYNCBUSY); // Wait for synchronization //NVIC_DisableIRQ(TC4_IRQn); //NVIC_ClearPendingIRQ(TC4_IRQn); NVIC_SetPriority(TC4_IRQn, 0); // Set the Nested Vector Interrupt Controller (NVIC) priority for TC4 to 0 (highest) NVIC_EnableIRQ(TC4_IRQn); // Connect TC4 to Nested Vector Interrupt Controller (NVIC) REG_TC4_INTFLAG |= TC_INTFLAG_OVF; // Clear the interrupt flags REG_TC4_INTENSET = TC_INTENSET_OVF; // Enable TC4 interrupts // REG_TC4_INTENCLR = TC_INTENCLR_OVF; // Disable TC4 interrupts REG_TC4_CTRLA |= TC_CTRLA_PRESCALER_DIV1024 | // Set prescaler to 1024, 48MHz/1024 = 46.875kHz TC_CTRLA_WAVEGEN_MFRQ | // Put the timer TC4 into match frequency (MFRQ) mode TC_CTRLA_ENABLE; // Enable TC4 while (TC4->COUNT16.STATUS.bit.SYNCBUSY); // Wait for synchronization }