#include "Arduino.h"
char pwmPin = 5; // OC3A (timer 3, Output compare A), PE3 (port E sortie 3)
char clockBits;
volatile uint32_t count;
int32_t max_count;
uint16_t diviseur[6] = {0,1,8,64,256,1024};
void pulse_train(uint32_t period, int32_t nombre, float rapport) {
//void pulse_train(uint32_t period, int32_t nombre, float impuls) {
//void pulse_train(uint32_t period, int32_t nombre) {
TCCR3A = 0;
TCCR3A |= (1 << COM3A1) | (1 << COM3A0);
TCCR3B = 1 << WGM13; // phase and frequency correct pwm mode, top = ICR3
uint32_t icr = (F_CPU/1000000*period/2);
int d = 1;
while ((icr>0xFFFF)&&(d<5)) {
d++;
icr = (F_CPU/1000000*period/2/diviseur[d]);
}
clockBits = d;
uint16_t ocra = icr * (1.0-rapport);
//uint16_t ocra = icr-impuls/2;
ICR3 = icr;
//OCR3A = ocra;
OCR3A = 448;
TIMSK3 = 1 << TOIE3; // overflow interrupt enable quand TCNT > ICR
sei();
count = 0;
max_count = nombre+1;
TCNT3 = 0; // mise à zéro du compteur
TCCR3B |= clockBits;
//sei();
}
void pulse_on () {
TCCR3B |= clockBits;
}
ISR(TIMER3_OVF_vect) { // Overflow interrupt
//ZSTEP_ON();
calcul_Ti(); // calcul du pas suivant (sert aussi de tempo!)
//ZSTEP_TOGG();
count++;
if (count==max_count) {
TCCR3B &= ~0x7; // stoppe le Timer
TCCR3A = 0;
PORTE &= ~(1 << PORTE3);
TCNT3 = 0;
}
}
/*---------------------------------------------------------------------*/
unsigned int TMax = 1000; // durée du pas de départ (µs)
// Tmax détermine l'accélération
// TMax=2000 => accélération=9.377 m/s²
// et vitesse de départ = 9.4 mm/min
unsigned int TMax_Haut = TMax; // en montée
unsigned int TMax_Bas = TMax * 2; // en descente
unsigned int TLong = TMax; // dans la boucle moteur
unsigned int Tmin = 70; // durée mini du pas = vitesse maxi
// 187:6000 mm/min - 200:5600 mm/min - 300:3750 mm/min
unsigned int Tstop = TMax / 2; // durée mini du pas pour arrêt brutal (doit etre inferieur a TMax/2)
/*---------------------------------------------------------------------*/
volatile float Ti = TMax; // durée du pas (entre 2 impulsions)
volatile float Ti2 = 0; // (V02.21 : float)
volatile uint16_t m = 0; // ralentissement : nombre de pas (calculé en temps réel)
volatile long n = 1; // index du pas moteur dans la rampe d'accélération
volatile long i = 1; // incrément pour calcul du pas moteur
unsigned int nech = 10; // nombre d'échantillons
unsigned int seuil = 0; // écart accepté avec tension de consigne (vRef)
unsigned int vRef0 = 78; // tension de référence initiale
unsigned int vRef = vRef0; // tension de référence en cours
/*---------------------------------------------------------------------*/
void calcul_Ti() { // (duree fonction : 70 µs environ)
Ti2 = Ti;
if (m != 0) {
n = i - m;
} else {
n = i;
}
Ti = Ti - (2 * Ti) / (4 * n + 1);
i = i + 1;
if (Ti > TLong) {
Ti = TLong;
} else if (Ti < Tmin) {
Ti = Tmin; // ne pas depasser la vitesse max, bloquer i
i = i - 1; // et donc n pour calculer m
}
ICR3 = Ti*8; // 8 clockBits / µs
OCR3A = ICR3 -160; // largeur impulsion 20 µs * 8 (car diviseur 1 du Timer)
//TCNT3 = 0; // ok ???
}
void setup() {
DDRE |= 1 << PORTE3; // data direction register
PORTE &= ~(1 << PORTE3);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
}
void loop() {
Ti = 350;
pulse_train(Ti,40,0.2); // periode, nombre, rapport
//pulse_train(150,2); // periode, nombre (durée fixe)
//pulse_train(70,4,0.2); // periode, nombre (durée fixe)
delay (10000);
}