1/160 - Echelle N

Le Forum consacré à l'Echelle N
 
AccueilAccueil  PortailPortail  ÉvènementsÉvènements  Dernières imagesDernières images  S'enregistrerS'enregistrer  Connexion  
N'hésitez pas à consulter le calendrier et les événements du forum pour voir les manifestations près de chez vous !
Le deal à ne pas rater :
Pokémon EV06 : où acheter le Bundle Lot 6 Boosters Mascarade ...
Voir le deal

 

 Plaque tournante (impression 3D & commande Arduino)

Aller en bas 
+6
Derf
duchemin
Traindenfer
Psychobug
romilly
macsddau
10 participants
Aller à la page : Précédent  1, 2
AuteurMessage
macsddau
Membre



Masculin Age : 51
Localisation : France
Nombre de messages : 54
Date d'inscription : 21/10/2013

Plaque tournante (impression 3D & commande Arduino) - Page 2 Empty
MessageSujet: Re: Plaque tournante (impression 3D & commande Arduino)   Plaque tournante (impression 3D & commande Arduino) - Page 2 Icon_minitimeVen 27 Mar - 17:55

murielle a écrit:
c'est superbe et si tu en a une en trop...
Quand je vois la finesse de ta gare d'Elbeuf, je pense que tu serai déçu par ma réalisation.
Revenir en haut Aller en bas
Invité
Invité




Plaque tournante (impression 3D & commande Arduino) - Page 2 Empty
MessageSujet: Re: Plaque tournante (impression 3D & commande Arduino)   Plaque tournante (impression 3D & commande Arduino) - Page 2 Icon_minitimeSam 28 Mar - 10:34

Ta réalisation semble vraiment clean !

Comment compte tu peindre ?
Revenir en haut Aller en bas
macsddau
Membre



Masculin Age : 51
Localisation : France
Nombre de messages : 54
Date d'inscription : 21/10/2013

Plaque tournante (impression 3D & commande Arduino) - Page 2 Empty
MessageSujet: Re: Plaque tournante (impression 3D & commande Arduino)   Plaque tournante (impression 3D & commande Arduino) - Page 2 Icon_minitimeSam 28 Mar - 12:26

Wapata a écrit:
Ta réalisation semble vraiment clean !
Les photos masquent bien les défauts. Il ne faut pas voir de près.
Wapata a écrit:
Comment compte tu peindre ?
Tu touche là mon plus gros problème. Tant que c'est de la technique tout vas bien mais pour la décoration je suis pas doué.
Je devrais peindre à l'Aérographe. Donc démontage, peinture puis remontage...
Revenir en haut Aller en bas
SUPERN
Membre
Membre
SUPERN


Masculin Age : 76
Localisation : Charente Maritime
Nombre de messages : 306
Date d'inscription : 24/06/2013

Plaque tournante (impression 3D & commande Arduino) - Page 2 Empty
MessageSujet: Re: Plaque tournante (impression 3D & commande Arduino)   Plaque tournante (impression 3D & commande Arduino) - Page 2 Icon_minitimeLun 20 Avr - 18:21

Bonsoir,

Beau projet! Personnellement je suis intéressé par la commande arduino car j'ai une plaque manuelle...
En fait il y a un moteur DC et un bouton de commande mais c'est pas pilotable par PC.
Donc si tu pouvais détailler ta commande je te suivrai avec attention

Mais pas d'urgence, je suis encore au stade des tests unitaires de mes composants!
A+
Yves
Revenir en haut Aller en bas
macsddau
Membre



Masculin Age : 51
Localisation : France
Nombre de messages : 54
Date d'inscription : 21/10/2013

Plaque tournante (impression 3D & commande Arduino) - Page 2 Empty
MessageSujet: Re: Plaque tournante (impression 3D & commande Arduino)   Plaque tournante (impression 3D & commande Arduino) - Page 2 Icon_minitimeLun 20 Avr - 18:40

SUPERN a écrit:
Personnellement je suis intéressé par la commande arduino car j'ai une plaque manuelle...
En fait il y a un moteur DC et un bouton de commande mais c'est pas pilotable par PC.
Actuellement je travail sur le fonctionnement du moteur. Je suis allé un peu vite dans la sélection du "Motor Shield Arduino"; contrairement au driver Populu, celui-ci n'intègre pas de limitation de courant. Sous 12V ça chaaaaauf ! Mais c'est plus simple a câbler avec la carte Arduino.
J'ai donc choisi d'écrire en C un driver permettant la limitation de courant. Il est basé sur les Timer et les interruptions de l'ATmega328P. Voici ce que ça donne et c'est pas gagné Crying or Very sad  

affraid ATTENTION ! affraid  le programme ne fonctionne pas actuellement. Il est programmé avec XAVR.

main.c
Code:
#include "ArduinoMotorShieldStepper.h"

#define PI 3.14159265358979323846

// motor definition
#define stepsPerRevolution  200     //steps
#define currentLimit        1.68    //A

inline void initIO(void) {
    setupStepper(stepsPerRevolution, currentLimit);
}

int main(void) {
   initIO();

   while (1) {
        if (stepCount() == 0) {
            setSpeed(2 * PI);//rad/s
            
            rotate(2 * PI);// rad
        }
   }

   return 0;
}
ArduinoMotorShieldStepper.h
Code:
//  ArduinoMotorShieldStepper.h
#ifndef ArduinoMotorShieldStepper_h
#define ArduinoMotorShieldStepper_h

#include <inttypes.h>

extern void setupStepper(uint16_t, float);
extern void setSpeed(float);
extern void rotate(float);
extern uint32_t stepCount(void);

#endif
ArduinoMotorShieldStepper.c
Code:
//  ArduinoMotorShieldStepper.c
#include "ArduinoMotorShieldStepper.h"

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

#define PI 3.14159265358979323846
#define abs(a) (a < 0 ? -a : a)

// Arduino motor shield sensor caracteristics
#define SENSOR_RESISTOR         0.15    // sensor resistor value (R1 & R2 on Arduino Motor Shiled)
#define SENSOR_VOLTAGE          2.3     // sensor max voltage
#define SENSOR_FACTOR           2

extern uint8_t sensorFractor(uint16_t);
extern void pwmOn(void);
extern void pwmOff(void);
extern void pwmAOn(void);
extern void pwmBOn(void);
extern void pwmAOff(void);
extern void pwmBOff(void);
extern void motionOn(void);
extern void motionOff(void);
extern void sensorStart(void);
extern void sensorASelect(void);
extern void sensorBSelect(void);
extern uint8_t sensorA(void);

// stepper speed definitions
#define MONTION_PS_COUNT    7
const uint16_t PROGMEM MOTION_PS_FACTOR[] = {
    1024,
    256,
    128,
    64,
    32,
    8,
    1
};

const uint8_t PROGMEM MOTION_PS_SETTING[] = {
    (0 << CS12) | (0 << CS11) | (0 << CS10),
    (0 << CS12) | (1 << CS11) | (0 << CS10),
    (0 << CS12) | (1 << CS11) | (1 << CS10),
    (1 << CS12) | (0 << CS11) | (0 << CS10),
    (1 << CS12) | (0 << CS11) | (1 << CS10),
    (1 << CS12) | (1 << CS11) | (0 << CS10),
    (1 << CS12) | (1 << CS11) | (1 << CS10)
};

const uint32_t PROGMEM MOTION_PS_FREQUENCE[] = {
    3906,
    15625,
    31250,
    62500,
    125000,
    500000,
    4000000
};

volatile uint8_t    _direction          = 1;
volatile uint32_t   _count              = 0;
volatile uint8_t    _step               = 1;

typedef struct {
    uint16_t stepsPerRevolution;
    float currentLimit;
} stepperMotor_t;
stepperMotor_t _motor;

inline void setupStepper(uint16_t someStepPerRevolution, float aCurrentLimit) {
    _motor.stepsPerRevolution = someStepPerRevolution;
    _motor.currentLimit = aCurrentLimit;
    
    // DIR A on arduino pin 12 (PB4)
    // DIR B on arduino pin 13 (PB5)
    // PWM A on arduino pin 3 (PD3)
    // PWM B on arduino pin 11 (PB3)
    // BREAK A on arduino pin 8 (PB0)
    // BREAK B on arduino pin 9 (PB1)
    DDRB |= (1 << DDB5) | (1 << DDB4) | (1 << DDB3)| (1 << DDB1) | (1 << DDB0) ;
    DDRD |= (1 << DDD3);

    // MOTION trigger with TIMER0
    //  COM0A1:0    = 1 : toggle the OUTPUT COMPARE MATCH A for testing
    //  COM0B1:0    = 0 : nothing with OUTPUT COMPARE MATCH B.
    //  WGM02:1     = 2 : CTC mode.
    //  CS02:1      = 0 : PS not set. Defined in setSpeed Method.
    TCCR0A |= (0 << COM0A1) | (1 << COM0A0) | (0 << COM0B1) | (0 << COM0B0) | (1 << WGM01) | (0 << WGM00);
    TCCR0B |= (0 << WGM02) | (0 << CS02) | (0 << CS01) | (0 << CS01);
    DDRD |= (1 << DDD6);// output the motion trigger on PD6 (Arduino pin 6)
    
    // PWM setup with TIMER2
    //  COM2A1:0    = 0 : No OUTPUT COMPARE MATCH A at startup
    //  COM2B1:0    = 0 : No OUTPUT COMPARE MATCH B at startup
    //  WGM22:0     = 3
    //      1 = Phase correct PWM
    //      2 = CTC
    //      3 = Fast PWM
    //  CS22:0      = 1 : Prescalar
    TCCR2A |= (0 << COM2A1) | (0 << COM2A0) | (0 << COM2B1) | (0 << COM2B0) | (0 << WGM21) | (1 << WGM20);
    TCCR2B |= (0 << WGM22) | (0 << CS22) | (1 << CS21) | (0 << CS20);

    // SENSOR setup
    PRR &= ~(1 <<PRADC);
    //  ADEN    = 1 : Analog to Digital Enabled
    //  ADIE    = 1 : Analog to Digital Interrupt Enabled
    //  ADPS2:0 = 1 :
    ADCSRA |= (1 << ADEN) | (1 << ADIE) | (0 << ADPS2) | (0 << ADPS1) | (1 << ADPS0);
    //  ADC1:0D = 3 : ADC1 & ADC0 input enabled
    DIDR0 |= (1 << ADC1D) | (1 << ADC0D);
    //  MUX3:0  = 0 : Clear all. Select ADC0 for first input conversion
    ADMUX &= ~((1 << MUX3) | (1 << MUX2) | (1 << MUX1) | (1 << MUX0));
    //  start analog to digitial conversion

    // before strating
    //  clear BREAK pin to allow motion with Arduino Motor Shield
    PORTB &= ~(1 << PORTB0);
    PORTB &= ~(1 << PORTB1);
    sensorStart();
    pwmOn();

    // enable all interrupts
    sei();
}

void setSpeed(float aSpeed) {
    //calcul de la fréquence des impultions
    float focnx = abs(aSpeed) * _motor.stepsPerRevolution;
    uint8_t N =  0;
    while ((focnx > MOTION_PS_FREQUENCE[N]) && (N < MONTION_PS_COUNT)) {
        N++;
    }
    
    motionOff();//suspendre l'interruption
    
    //réglage du préscalaire
    TCCR0B &= ~((1 << CS02) | (1 << CS01) | (1 << CS00));
    TCCR0B |= MOTION_PS_SETTING[N];
    
    //réglage de la valeur TOP
    OCR0A = (F_CPU / (2 * MOTION_PS_FACTOR[N] * focnx)) - 1;
    
    motionOn();//reprendre l'interruption
}

void rotate(float anAngle) {
    _count = 2 * abs(anAngle) * _motor.stepsPerRevolution / (2 * PI);
    _direction = anAngle > 0 ? 1 : -1;
}

inline uint32_t stepCount(void) {
    return _count;
}

inline uint8_t sensorFactor(uint16_t aValue) {
    // compute PWM factor according to motor max current
    float current = SENSOR_FACTOR * SENSOR_RESISTOR * (aValue * 5.0 / 1023);
    return 255 * (current < _motor.currentLimit ?
                  1 :
                  current / _motor.currentLimit / SENSOR_FACTOR);
}

inline void pwmOn() {
    pwmAOn();
    pwmBOn();
}

inline void pwmOff() {
    pwmAOff();
    pwmBOff();
}

inline void pwmAOn() {
    PORTD |= (1 << PORTD3);
    TCCR2A &= ~((1 << COM2A1) | (1 << COM2A0));
}

inline void pwmBOn() {
    PORTB |= (1 << PORTB3);
    TCCR2A &= ~((1 << COM2B1) | (1 << COM2B0));
}

inline void pwmAOff(void) {
    TCCR2A &= ~((1 << COM2A1) | (1 << COM2A0));
    PORTD &= ~(1 << PORTD3);
}

inline void pwmBOff(void) {
    TCCR2A &= ~((1 << COM2B1) | (1 << COM2B0));
    PORTB &= ~(1 << PORTB3);
}

inline void motionOn() {
    TIMSK0 |= (1 << OCIE0A);
}

inline void motionOff() {
    TIMSK0 &= ~(1 << OCIE0A);
}

inline void sensorStart() {
    ADCSRA |= (1 << ADSC);
}

inline void sensorASelect() {
    ADMUX &= ~((1 << MUX3) | (1 << MUX2) | (1 << MUX1) | (1 << MUX0));
}

inline void sensorBSelect() {
    ADMUX &= ~((1 << MUX3) | (1 << MUX2) | (1 << MUX1) | (1 << MUX0));
    ADMUX |= (1 << MUX0);
}

inline uint8_t sensorA() {
    return !(ADMUX & (1 << MUX0));
}

ISR(TIMER0_COMPA_vect) {
    if (_count > 0) {
        if (_direction > 0) {
            switch (_step) {//conter clockwise
                case 1:
                    pwmAOff();
                    PORTB |= (1 << PORTB5);
                    pwmBOn();
                    break;
                case 2:
                    pwmBOff();
                    PORTB &= ~(1 << PORTB4);
                    pwmAOn();
                    break;
                case 3:
                    pwmAOff();
                    PORTB &= ~(1 << PORTB5);
                    pwmBOn();
                    break;
                case 4:
                    pwmBOff();
                    PORTB |= (1 << PORTB4);
                    pwmAOn();
                    break;
            }
        } else {
            switch (_step) {//clockwise
                case 1:
                    pwmBOff();
                    PORTB |= (1 << PORTB4);
                    pwmAOn();
                    break;
                case 2:
                    pwmAOff();
                    PORTB &= ~(1 << PORTB5);
                    pwmBOn();
                    break;
                case 3:
                    pwmBOff();
                    PORTB &= ~(1 << PORTB4);
                    pwmAOn();
                    break;
                case 4:
                    pwmAOff();
                    PORTB |= (1 << PORTB5);
                    pwmBOn();
                    break;
            }
        }
        _count -= 1;
        _step += 1;
        if (_step > 4) {
            _step = 1;
        }
    }
}

ISR(ADC_vect) {
    if (sensorA()) {
        OCR2B = sensorFactor(ADC);
        sensorBSelect();
    } else {
        OCR2A = sensorFactor(ACD);
        sensorASelect();
    }
    sensorStart();
}
A suivre...
Revenir en haut Aller en bas
macsddau
Membre



Masculin Age : 51
Localisation : France
Nombre de messages : 54
Date d'inscription : 21/10/2013

Plaque tournante (impression 3D & commande Arduino) - Page 2 Empty
MessageSujet: Re: Plaque tournante (impression 3D & commande Arduino)   Plaque tournante (impression 3D & commande Arduino) - Page 2 Icon_minitimeLun 27 Avr - 1:28

Après une semaine, la bibliothèque du moteur pas à pas semble fonctionner. En voici le code :
main.c
Code:
#include "ArduinoMotorShieldStepper.h"

#define PI 3.14159265358979323846

// motor definition
#define stepsPerRevolution  200     //steps
#define currentLimit        1.68    //A

#define PULLEY_1            18
#define PULLEY_2            54

#define STAGE_COUNT         24

#define SPEED               1//rpm

void initIO(void) {
    stepperSetup(stepsPerRevolution, currentLimit);
}

int main(void) {
    initIO();
    
    unsigned int speed;
    
    while (1) {
        speed = SPEED * (PULLEY_2 / PULLEY_1);//rpm
        stepperSpeed(speed * PI / 30);//rad.s-1
        
        stepperRotate(2 * PI);// rad
        while (stepperCount()) {
        }
    }
    
   return 0;
}
ArduinoMotorShieldStepper.h
Code:
#ifndef ArduinoMotorShieldStepper_h
#define ArduinoMotorShieldStepper_h  0.07

extern void stepperSetup(unsigned int, float);
extern void stepperSpeed(float);    //  0,076293944 <= speed <= 4,00E+06
extern void stepperRotate(float);
extern unsigned long stepperCount(void);

#endif
ArduinoMotorShieldStepper.c
Code:
#include "ArduinoMotorShieldStepper.h"

#include <avr/io.h>
#include <avr/interrupt.h>

extern void dirA_P(void);
extern void dirA_N(void);
extern void dirB_P(void);
extern void dirB_N(void);
extern void pwmA_On(void);
extern void pwmA_Off(void);
extern void pwmB_On(void);
extern void pwmB_Off(void);
extern void sensorStart(void);
extern unsigned char sensorFractor(unsigned int);
extern void sensorSelect(unsigned char);

#define PI 3.14159265358979323846
#define abs(a) (a < 0 ? (-a) : a)
#define max(a,b) (a < b ? b : a)

#define SHIELD_SENS_RESITOR         0.15    // Serial resistor for current sensing
#define SHIELD_OA_GROUND_RESISTOR   1000    // multiplier non inverter OA ground resistor
#define SHIELD_OA_FEEDBACK_RESOSTOR 10000   // multiplier non inverter OA feedback resistor

#define ADC_REF_VOLTAGE             5.0

#define SENSOR_SAFETY_FACTOR        24

#define SENSOR_MASK                 0b00001111  // MUX3:0 = 15
#define SENSOR_A                    0b00000000  // MUX3:0 = 0, ADC0
#define SENSOR_B                    0b00000001  // MUX3:0 = 1, ADC1

#define STEPPING_FACTOR             1

// stepper speed definitions
#define STEPPER_SETTING_COUNT       5
static const unsigned int STEPPER_PS_FACTOR[] = {
    1024,
    256,
    64,
    8,
    1
};

static const unsigned char STEPPER_PS_SETTING[] = {
    (1 << CS12) | (0 << CS11) | (1 << CS10),
    (1 << CS12) | (0 << CS11) | (0 << CS10),
    (0 << CS12) | (1 << CS11) | (1 << CS10),
    (0 << CS12) | (1 << CS11) | (0 << CS10),
    (0 << CS12) | (0 << CS11) | (1 << CS10)
};


static      unsigned int    _stepsPerRevolution = 0;
volatile    float           _currentLimit       = 0;
volatile    unsigned char   _direction          = 1;
volatile    unsigned long   _count              = 0;
volatile    unsigned char   _step               = 1;

// stepper functions ******************************************************************************

void stepperSetup(unsigned int someStepPerRevolution, float aCurrentLimit) {
    _stepsPerRevolution = someStepPerRevolution;
    _currentLimit = aCurrentLimit;
    
    //      PUD     = 1 : disable internal pullup
    MCUCR |= (1 << PUD);

    // enable interrupts
    sei();

    // SENSOR setup :
    //      SENS_A on ADC0 (PC0)
    //      SENS_B on ADC1 (PC1)
    //
    //      ADEN    = 1 : Analog to Digital Enabled
    //      ADSC    = 0 : do not start conversion
    //      ADATE   = 0 : no auto triggering
    //      ADIF    = 0 : do not force interrupt
    //      ADIE    = 1 : Analog to Digital Interrupt Enabled
    //      ADPS2:0 = 7 : F_CPU/128   -> 125kHz
    ADCSRA |= (1 << ADEN) | (0 << ADSC) | (0 << ADATE) | (0 << ADIF) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
    //      ADTS2:0 = 0 : no auto trigger modes
    //ADCSRB |= (0 << ADTS2) | (0 << ADTS1) | (0 << ADTS0);
    //      ADC5D:0 = 3 : ADC1 & ADC0 digital input disabled
    DIDR0 |= (0 << ADC5D) | (0 << ADC4D) | (0 << ADC3D) | (0 << ADC2D) | (1 << ADC1D) | (1 << ADC0D);
    //      REFS1:0 = 1 : 5V Internal VRef
    //      MUX3:0  = 0 : Select ADC0 at startup
    ADMUX |= (0 << REFS1) | (1 << REFS0) | (0 << MUX3) | (0 << MUX2) | (0 << MUX1) | (0 << MUX0);
    //      start sensing
    sensorStart();
    
    // motor PWM modulation with TIMER2 :
    //      COM2A1:0    = 0 : no output at stratup, use pwmA_on() or pwmA_off()
    //      COM2B1:0    = 0 : no output at stratup, use pwmB_on() or pwmB_off()
    //      WGM22:0     = 3 : Fast PWM
    TCCR2A |= (0 << COM2A1) | (0 << COM2A0) | (0 << COM2B1) | (0 << COM2B0) | (1 << WGM21) | (1 << WGM20);
    //      FOC2x       = 0 : do not focrce output
    //      CS22:0      = 1 : F_CPU/1 -> 16MHz
    TCCR2B |= (0 << FOC2A) | (0 << FOC2B) | (0 << WGM22) | (0 << CS22) | (0 << CS21) | (1 << CS20);
    //      OCIE2B      = 0 : no compare match 2B interrupt
    //      OCIE2A      = 0 : no compare match 2A interrupt
    //      TOIE2       = 0 : no overflow interrupt
    //TIMSK2 |= (0 << OCIE2B) | (0 << OCIE2A) | (0 << TOIE2);
    
    // motor step timing with TIMER1 (16 bits)
    //      COM1A1:0    = 0 : no output
    //      COM1B1:0    = 1 : monotoring output compare match 1B, toggle OC1B (PB2, arduino pin 10)
    //      WGM12:1     = 4 : CTC mode.
    TCCR1A |= (0 << COM1A1) | (0 << COM1A0) | (0 << COM1B1) | (1 << COM1B0) | (0 << WGM11) | (0 << WGM10);
    //      FOC1x       = 0 : do not focrce output
    //      CS12:0      = 0 : no clk source, timer stoped, defined with stepperSpeed()
    TCCR1B |= (0 << FOC1A) | (0 << FOC1B) | (1 << WGM12) | (0 << CS12) | (0 << CS11) | (0 << CS10);
    //      OCIE1B      = 0 : no compare match 1B interrupt
    //      OCIE1A      = 1 : compare match 1A interrupt enabled
    //      TOIE1       = 0 : no overflow interrupt
    TIMSK1 |= (0 << OCIE1B) | (1 << OCIE1A) | (0 << TOIE1);

    // Output pins :
    //      DDB7:6      = 0 : unused
    //      DDB5        = 1 : DIR B, Arduino pin 13
    //      DDB4        = 1 : DIR A, Arduino pin 12
    //      DDB3        = 1 : PWM B, OC2A, Arduino pin 11
    //      DDB2        = 1 : OC1B, PB2, Arduino pin 10, monitoring stepping timer
    //      DDB1        = 1 : BRK B, Arduino pin 9
    //      DDB0        = 1 : BRK A, Arduino pin 8
    DDRB |= (0 << DDB7) | (0 << DDB6) | (1 << DDB5) | (1 << DDB4) | (1 << DDB3) | (1 << DDB2) | (1 << DDB1) | (1 << DDB0);
    //      DDD7:4,2:0  = 0 : unused
    //      DDD3        = 1 : PWM A, OC2B, Arduino pin 3
    DDRD |= (0 << DDD7) | (0 << DDD6) | (0 << DDD5) | (0 << DDD4) | (1 << DDD3) | (0 << DDD2) | (0 << DDD1) | (0 << DDD0);
}

void stepperSpeed(float aSpeed) {
    //aSpeed : speed in rad/s
    //compute TIMER0 prescalar and OUTPUT COMPARE REGISTER 0A according to the speed
    
    //selecting timer prescalar
    float foc1A = abs(aSpeed) * _stepsPerRevolution * STEPPING_FACTOR;
    unsigned char n = 0;
    while ((foc1A > (F_CPU / STEPPER_PS_FACTOR[n] / STEPPING_FACTOR)) && (n < STEPPER_SETTING_COUNT)) {
        n++;
    }
    
    //clear prescalar, stop timer
    TCCR1B &= ~((1 << CS12) | (1 << CS11) | (1 << CS10));
    //réglage de la valeur TOP
    // set OCR1B to the same value for monitoring
    OCR1A = OCR1B = max((12 * F_CPU / (2 * STEPPER_PS_FACTOR[n] * foc1A)) - 1, 1);
    // TCNT1    = 0 : clear, restart from 0
    TCNT1 = 0;
    //set prescalar, restart timer
    TCCR1B |= STEPPER_PS_SETTING[n];
}

void stepperRotate(float anAngle) {
    //anAngle : angle in radians
    
    _count = STEPPING_FACTOR * abs(anAngle) * _stepsPerRevolution / PI / 2;
    _direction = anAngle > 0 ? 1 : 0;
}

unsigned long stepperCount() {
    return _count;
}

// Stepping functions *******************************************************************

inline void dirA_P() {
    PORTB |= (1 << PORTB4);
}

inline void dirA_N() {
    PORTB &= ~(1 << PORTB4);
}

inline void dirB_P() {
    PORTB |= (1 << PORTB5);
}

inline void dirB_N() {
    PORTB &= ~(1 << PORTB5);
}

inline void pwmA_On() {
    //      COM2B1:0    = 2 : OUTPUT COMPARE 2B pin set at BOTTOM, clear on COMPARE MATCH
    TCCR2A |= (1 << COM2B1);
}

inline void pwmA_Off() {
    TCCR2A &= ~(1 << COM2B1);
    PORTD &= ~(1 << PORTD3);
}

inline void pwmB_On() {
    //      COM2A1:0    = 2 : OUTPUT COMPARE 2A pin set at BOTTOM, clear on COMPARE MATCH
    TCCR2A |= (1 << COM2A1);
}

inline void pwmB_Off() {
    TCCR2A &= ~(1 << COM2A1);
    PORTB &= ~(1 << PORTB3);
}

ISR(TIMER1_COMPA_vect) {
    if (_count > 0) {
        switch (_direction) {
            case 0:
                switch (_step) {//clockwise
                    case 1:
                        pwmA_Off();
                        dirB_N();
                        pwmB_On();
                        break;
                    case 2:
                        pwmB_Off();
                        dirA_N();
                        pwmA_On();
                        break;
                    case 3:
                        pwmA_Off();
                        dirB_P();
                        pwmB_On();
                        break;
                    case 4:
                        pwmB_Off();
                        dirA_P();
                        pwmA_On();
                        break;
                }
                break;
                
            case 1:
                switch (_step) {//conter clockwise
                    case 1:
                        pwmB_Off();
                        dirA_P();
                        pwmA_On();
                        break;
                    case 2:
                        pwmA_Off();
                        dirB_P();
                        pwmB_On();
                        break;
                    case 3:
                        pwmB_Off();
                        dirA_N();
                        pwmA_On();
                        break;
                    case 4:
                        pwmA_Off();
                        dirB_N();
                        pwmB_On();
                        break;
                }
                break;
        }
        _step++;
        if ( _step > (4 * STEPPING_FACTOR) ) {
            _step = 1;
        }
        _count--;
    }
}

// Sensor function ********************************************************************

inline void sensorStart() {
    //  ADSC    = 1 : start analog to digital conversion
    ADCSRA|=(1<<ADSC);
}

inline unsigned char sensorFactor(unsigned int aValue) {
    float current = SENSOR_SAFETY_FACTOR * (aValue * ADC_REF_VOLTAGE / 1024) / (1 + SHIELD_OA_FEEDBACK_RESOSTOR / SHIELD_OA_GROUND_RESISTOR) / SHIELD_SENS_RESITOR;
    return max(255 * (current < _currentLimit ? 1 : _currentLimit / current), 1);
}

inline void sensorSelect(unsigned char aSensor) {
    //  MUX3:0  = 0 : clear MUX
    ADMUX &= ~SENSOR_MASK;
    //  MUX3=0  = sensor : set MUX to sensor
    ADMUX |= aSensor;
}

ISR(ADC_vect) {
    switch (ADMUX & SENSOR_MASK) {
        case SENSOR_A:
            // set OUTPUT COMPARE REGISTER 2B
            OCR2B = sensorFactor(ADC);
            sensorSelect(SENSOR_B);
            break;
            
        case SENSOR_B:
            // set OUTPUT COMPARE REGSITER 2A
            OCR2A = sensorFactor(ADC);
            sensorSelect(SENSOR_A);
            break;
     }
    sensorStart();
}
Alimenté sous 12V le moteur et le Shield Motor Arduino ne chauffent plus Very Happy grâce à la commande en PWM des bobines. J'ai réussi à faire tourner le moteur de 1 à 240 tr/mn sans problème. En fonctionnement, la plaque tournante tournera à 1 tr/mn et le moteur à 3 tr/mn car le rapport de transmission est de 54/18=3. J'ai encore un problème de vitesse. Elle est légèrement supérieure; à 1 tr/mn la minute ne fait que 57s Embarassed . Je cherche...

Un petit rappel : pour utiliser ce code il faut utiliser "xavr". Il débarrasse la programme de toutes les spécificité du langage Arduino mais ne fonctionne qu'en C. Pas de programmation objet Crying or Very sad .
Revenir en haut Aller en bas
Contenu sponsorisé





Plaque tournante (impression 3D & commande Arduino) - Page 2 Empty
MessageSujet: Re: Plaque tournante (impression 3D & commande Arduino)   Plaque tournante (impression 3D & commande Arduino) - Page 2 Icon_minitime

Revenir en haut Aller en bas
 
Plaque tournante (impression 3D & commande Arduino)
Revenir en haut 
Page 2 sur 2Aller à la page : Précédent  1, 2
 Sujets similaires
-
» Plaque tournante Arnold
» connexion Plaque tournante ARNOLD 6381 avec commande 6385
» Coulisse sur plaque tournante
» Plaque tournante
» Petite plaque tournante

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
1/160 - Echelle N :: Modèles réduits à l'echelle N :: Les installations fixes-
Sauter vers: