Go Down

Topic: ATMEGA comme contrôleur I2C pour 12 servos (Read 157 times) previous topic - next topic

RandomCraftr

Bonjour,

voici un projet fini. Je croyais être très original, mais après une recherche je trouve pas mal de résultats sur le forum en anglais. Comme je me suis arraché sur ce mini projet (2 atmega, dont un sur breadboard programmé par une carte Arduino "as ISP"), et tout ça sans me planter dans mes téléversements ... ouf) et que je l'ai bien documenté (mémoire de poisson rouge oblige), ben je le propose quand même et na.

Il a donc la seule originalité d'être récent et en français ...  :smiley-confuse:

Donc je veux programmer 12 servos d'un robot quadrupède. Ca me mange 12 pins de ma carte Arduino ... donc je cherche une solution, et je laisse tomber l'achat d'un contrôleur dédié. Certainement mieux, mais moins rigolo pour apprendre !

Alors voilà mon montage (interactif sur TinkerCAD ici.)



Et voici le code pour la carte maître, qui commande le changement de position des servos toutes les 2 secondes:
Code: [Select]
#include <Wire.h>

void setup()
{
  Wire.begin(1); // join i2c bus (address optional for master)
}

void loop()
{
  for (int position=0;position<=180;position+=10){
    Wire.beginTransmission(2); // Init transmission to device #2
    for (int idx_servo=0;idx_servo<12;idx_servo++){
      Wire.write(idx_servo); // Set first integer value on I2C bus as servo id
      Wire.write(position); // Set second integer value on I2C bus as servo position
    }
    Wire.endTransmission(); // Flush I2C bus to trigger slave action on information
    delay(2000); // Wait before next position change
  }
}


Et celui de la carte esclave:
Code: [Select]
#include <Wire.h>
#include <Servo.h> // Include Servo library

Servo servo_array[12]; // Instanciate Servo object array
int servo_position[12]; // Instanciate Servo position array

void setup()
{
  Wire.begin(2);                // Join i2c bus with address #2
  Wire.onReceive(receiveEvent); // Register event to trigger when I2C communicates
  Serial.begin(9600);
  for(int servo_idx=0;servo_idx <12;servo_idx++)
  {
    Serial.print("Init servo ");
    Serial.println(servo_idx);
    // Attach 12 servos on pin 3-13
    servo_array[servo_idx].attach(servo_idx+2);
    // Attach set all position values to 0
    servo_position[servo_idx] = 0;
  }
}

void loop()
{
  delay(100);
}

// Event to trigger when data is received on I2C bus
void receiveEvent(int howMany)
{
  Serial.println("Receiving ... "); 
  while(2 <= Wire.available()) // Capture two data at once
  {
    int servo_id = Wire.read(); // First integer is known as servo id
    int servo_pos = Wire.read(); // Second integer is known as servo position
    Serial.print("Send servo ");
    Serial.print(servo_id);
    Serial.print(" position ");
    Serial.println(servo_pos);
    servo_array[servo_id].write(servo_pos); // Set position to servo
  }
}


J'ai pas fait de traitement d'erreur, j'ai pas rencontré d'erreur sur le bus I2C pour l'instant, je sais pas si c'est une bêtise ou pas ?

Maintenant, je vais bosser le code de ma carte maître pour faire quelque chose qui avance, car un incrément de 10° sur 12 servos à la fois, ben ça n'avance pas très bien ...

Go Up