IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Code Arduino pour ATTINY 1606 MNR


Sujet :

Arduino

  1. #1
    Candidat au Club
    Homme Profil pro
    Technicien fabrication additive
    Inscrit en
    Juillet 2023
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien fabrication additive
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2023
    Messages : 3
    Par défaut Code Arduino pour ATTINY 1606 MNR
    Bonsoir à tous !

    Je recherche de l'aide pour un code implanté dans un ATTINY 1606 pour contrôler un moteur DC (encodeur, pont en H et PID) avec un signal STEP/DIR comme pour les moteurs pas à pas. Jusque là, le code marche avec le PID, l'attiny reçois bien les signaux STEP/DIR lors des essais avec un Arduino uno, mais 2 problèmes :

    - Le moteur ne tourne que dans un sens… Si je débranche/rebranche l'alimentation du PCB qui contient l'attiny, ca continue de tourner dans le même sens ou dans l'autre sens.

    -Si je débranche les fils des signaux STEP et DIR du Arduino le moteur continue de tourner quand même ...

    On dirait que les signaux arrivent à l'attiny mais ne ressortent "pas bien" sous la forme PWM pour alimenter le pont en H du moteur DC. Je précise que je suis encore débutant et que le code vient d'un projet open source qui n'est pas de moi.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
     
     
    #include <PID_v2.h>
    #include <EEPROM.h>
     
    // Type of Motordriver as is, with just an PWM Interface = true
    // DRV8803
    #define PWMCONTROL        1
    #define PWMMIN           65 // minimum value for PWM to turn the motor
    #define PWMMAX          200 // maximum value for PWM
     
    #define EEPIDADDR         1 // Adress for saved PID Values
     
    // Connect to Hall Sensor PCB
    #define encoder0PinA    2 // PA6
    #define encoder0PinB    3 // PA7
     
     
    #if PWMCONTROL
      #define MotorIN1        0 // PA4
      #define MotorIN2        1 // PA5
    #else
      #define MotorDIR        0 // PA4
      #define MotorPWM        1 // PA5
    #endif
     
    //from ramps 1.4 stepper driver
    #define STEP_PIN        12 // PC2
    #define DIR_PIN         11 // PC1
    #define EnableLED       15 // PB6
     
     
    volatile long encoder0Pos = 0;
     
    long GetSteps = 0;
     
    // PID default values 
    struct MyObject {
      double kp;
      double ki;
      double kd;
    };
    MyObject PIDvals = {
      7.00, 0.04, 0.20 // defaut values for PID
    };
     
    double input = 0, output = 0, setpoint = 0, error = 0;
    PID myPID(&input, &output, &setpoint, PIDvals.kp, PIDvals.ki, PIDvals.kd, DIRECT);  
     
    long LastInterval = 0;
    long previousMillis = 0;        // will store last time LED was updated
    bool dir     = false;
     
    // ---------------------- SETUP -----------------------
    void setup() { 
      Serial.begin(9600);
     
      pinMode(EnableLED, OUTPUT);
      digitalWrite (EnableLED, HIGH);
     
      // get Saved (EEPROM) or default PID Values
      MyObject PIDv;
      EEPROM.get(EEPIDADDR, PIDv);
      if(not (PIDv.kp > 0.01)){
         PIDv = {
            PIDvals.kp, PIDvals.ki, PIDvals.kd // defaut values
         };
      }
      myPID.SetTunings(PIDv.kp, PIDv.ki, PIDv.kd);
      Serial.println("Saved (EEPROM) or default PID Values:");
      Serial.println(PIDv.kp);
      Serial.println(PIDv.ki);
      Serial.println(PIDv.kd);
     
     
      // Set Pins 
      pinMode(encoder0PinA, INPUT); 
      pinMode(encoder0PinB, INPUT);  
     
    #if PWMCONTROL
      pinMode(MotorIN1, OUTPUT); 
      pinMode(MotorIN2, OUTPUT);
    #else
      pinMode(MotorDIR, OUTPUT); 
      pinMode(MotorPWM, OUTPUT);
    #endif
     
     
      //motor control Pins
      pinMode(STEP_PIN, INPUT_PULLUP);
      pinMode(DIR_PIN, INPUT);
     
      // Interupts for position and target steps 
      attachInterrupt(digitalPinToInterrupt(encoder0PinA), doEncoderMotor0, CHANGE);  // encoderA pin on interrupt
      attachInterrupt(digitalPinToInterrupt(STEP_PIN),     countStep,       RISING);  // interrupt to count steppules
     
      myPID.SetMode(AUTOMATIC);     //set PID in Auto mode
      myPID.SetSampleTime(2);     // refresh rate of PID controller
      myPID.SetOutputLimits(-255, 255); // this is the MAX PWM value to move motor
     
      Serial.println("start");
      Serial.println("Position ToPosition MotorPWM RealPWM");
     
      delay(2000);
      digitalWrite (EnableLED, LOW);
    } 
     
    // ---------------------- LOOP -----------------------
    void loop(){
     
      byte n = Serial.available();
      if (n != 0) {
        MyObject PIDv;
        PIDv.kp = Serial.parseFloat();
        PIDv.ki = Serial.parseFloat();
        PIDv.kd = Serial.parseFloat();
     
        // write only PID values in eeprom if not rubbish
        if( PIDv.kp > 0.00 && PIDv.ki > 0.00 && PIDv.kd > 0.00){
          MyObject PIDvals = {
            PIDv.kp, PIDv.ki, PIDv.kd // defaut values
          };
          Serial.println("Input PID values saved in eeprom:");
          EEPROM.put(EEPIDADDR, PIDvals);
     
          myPID.SetTunings(PIDv.kp, PIDv.ki, PIDv.kd);
        }
     
        // control PID values    
        Serial.println(PIDv.kp);
        Serial.println(PIDv.ki);
        Serial.println(PIDv.kd);
      }
     
      setpoint = GetSteps; // setpoint to Steps get from controller
      input = encoder0Pos; // real Position
      error = abs(setpoint - input);
      myPID.Compute();   // compute correct value
      int realpwm=0;
      if(error){
        realpwm = pwmOut(output);    // get PWM Value from PID calculated
      }
      else {
        realpwm = pwmOut(0);    // break
      }
     
      // Diganostic via serialplotter from arduino ide
      // Serial.println("Position ToPosition MotorPWM DIR");
      if(millis() - LastInterval > (abs(error) > 10 ? 100 : 1000)){
     
        if(output < PWMMIN){
          digitalWrite (EnableLED, HIGH); // signal that mcu is running
        }
     
        Serial.print(input);
        Serial.print(" ");
        Serial.print(setpoint);
        Serial.print(" ");
        Serial.print(output);
        Serial.print(" ");
        Serial.print(realpwm);
        Serial.println("");
     
        if(output < PWMMIN){
          digitalWrite (EnableLED, LOW);
        }
        LastInterval=millis();
      }
    }
     
    // ---------------------- SUBS -----------------------
    #if PWMCONTROL
    int pwmOut(int out) {
      int pwm = 0;
      if (out > 0) {
        // forward
        pwm = map(out, 0, 255, PWMMIN, PWMMAX );
        analogWrite ( MotorIN1, pwm );       
        digitalWrite ( MotorIN2, LOW );
      }
      else if (out < 0) {
        // reverse
        pwm = map(abs(out), 0, 255, PWMMIN, PWMMAX );
        digitalWrite ( MotorIN1, LOW );    // if REV < encoderValue motor move in reverse direction.   
        analogWrite ( MotorIN2, pwm );                      
      }
      else {
        // break
        digitalWrite ( MotorIN1, LOW );
        digitalWrite ( MotorIN2, LOW );
      }
      return pwm;
    }
    #else
    void pwmOut(int out) {                               
      if (out > 0) {
        analogWrite( MotorPWM, out );       
        digitalWrite ( MotorDIR ,LOW );
      }
      else {
        analogWrite( MotorPWM, abs(out) );                      
        digitalWrite ( MotorDIR, HIGH );    // if REV < encoderValue motor move in reverse direction.   
      }
    }
    #endif
     
    void doEncoderMotor0(){
      if (digitalRead(encoder0PinA) == HIGH) {   // found a low-to-high on channel A
        if (digitalRead(encoder0PinB) == LOW) {  // check channel B to see which way
                             // encoder is turning
          encoder0Pos = encoder0Pos - 1;         // CCW
        } 
        else {
          encoder0Pos = encoder0Pos + 1;         // CW
        }
      }
      else                                        // found a high-to-low on channel A
      { 
        if (digitalRead(encoder0PinB) == LOW) {   // check channel B to see which way
                              // encoder is turning  
          encoder0Pos = encoder0Pos + 1;          // CW
        } 
        else {
          encoder0Pos = encoder0Pos - 1;          // CCW
        }
      }
    }
     
    void countStep(){
      dir = digitalRead(DIR_PIN);
      if(dir == HIGH){
        GetSteps++;
      }
      else{
        GetSteps--;
      }
    }

  2. #2
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 582
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 582
    Par défaut
    Bonjour,

    Je n'ai pas regardé le code mais vu les symptômes, je pencherais plutôt vers un problème de câblage. Est-il possible de le voir (schéma et photo seraient top) ?

    Quand même, un coup d'œil détecte que les deux définitions de pwmOut ne sont pas cohérentes, la première renvoie un int et la seconde rien (void).

    Salutations

  3. #3
    Candidat au Club
    Homme Profil pro
    Technicien fabrication additive
    Inscrit en
    Juillet 2023
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien fabrication additive
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2023
    Messages : 3
    Par défaut
    Je pense aussi à un faux contact quelque part. Par contre, je n'ai pas compris votre seconde phrase ? avec le pwm.

    Attention sur la photo du circuit il n'est pas encore soudé.

    Cordialement
    Images attachées Images attachées   

  4. #4
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 582
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 582
    Par défaut
    Bonjour Tesla,

    Citation Envoyé par Tesla31 Voir le message
    ... je n'ai pas compris votre seconde phrase ? avec le pwm...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // lignes 172
    #if PWMCONTROL 
    int pwmOut(int out) { // retourne un entier
    // ...
    // lignes 194
    #else
    void pwmOut(int out) {  // ne retourne rien
    Salut

  5. #5
    Candidat au Club
    Homme Profil pro
    Technicien fabrication additive
    Inscrit en
    Juillet 2023
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien fabrication additive
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2023
    Messages : 3
    Par défaut
    Je vais regarder tout ça, après le code n'est pas de moi.

    Merci encore pour les renseignements !

  6. #6
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 582
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 582
    Par défaut
    Bonjour,

    Avec la masse omniprésente, je regarderais si toutes les pattes qui doivent être isolées de la masse les sont réellement. La patte en bas à droite de U1 semble un candidat possible sur la photo. Avec un multimètre en contrôle de continuité, c'est à la fois une opération facile et fastidieuse.

    Bon courage

Discussions similaires

  1. Demande d'aide pour modifier code Arduino
    Par DS-Dge dans le forum Arduino
    Réponses: 4
    Dernier message: 24/09/2018, 22h22
  2. Réponses: 0
    Dernier message: 21/05/2018, 21h14
  3. Réponses: 2
    Dernier message: 08/04/2004, 11h11
  4. [VB6] Code source pour modifier MsgBox
    Par khany dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 25/02/2003, 15h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo