Communication I2C Raspberry et Arduino

Bonjour à tous.
Je me permet de venir vers vous afin d’avoir quelques éclaircissements sur le fonctionnement du bus I2C entre un raspberry (maitre) et arduino (esclave).

Ma connexion I2C entre les 2 est fonctionelle.
Par contre, j’ai énormement de mal avec la partie code.
En effet, je souhaiterai piloter 2 moteurs branchés sur un monster moto shield branché lui même sur un arduino depuis mon raspberry.

Pourriez vous me donner quelques infos sur les commandes (Python coté Raspberry) afin que l’arduino écoute les requêtes de son maître et les execute?

Je vous remercie par avance de vos retours.

bonjour, coté arduino, rien de compliqué. il écoute en permanence pour voir si des infos arrivent. si rien, il écoute si quelque chose, il exécute. http://www.pihomeserver.fr/2013/08/13/raspberry-pi-home-server-arduino-lier-les-deux-via-bus-i2c/

Bonjour.
Merci de la réponse.
En fait j’avais déja vu cet article (d’ailleurs c’est celui ci qui m’a permis de créer la liaison I2C entre mes 2 périphériques).

Pour résumer, j’aimerai exploiter mon monster moto shield en lançant les requêtes depuis le raspi.
J’ai le code arduino du shield et en gros je souhaiterai l’adapter et lancer des script python qui active tels ou tels fonctionnalités du shield ( exemple avance, recule etc…).
Au cas ou, ci dessous le code du shield monstermotoshield

/*  MonsterMoto Shield Example Sketch
  date: 5/24/11
  code by: Jim Lindblom
  hardware by: Nate Bernstein
  SparkFun Electronics
 
 License: CC-SA 3.0, feel free to use this code however you'd like.
 Please improve upon it! Let me know how you've made it better.
 
 This is really simple example code to get you some basic
 functionality with the MonsterMoto Shield. The MonsterMote uses
 two VNH2SP30 high-current full-bridge motor drivers.
 
 Use the motorGo(uint8_t motor, uint8_t direct, uint8_t pwm) 
 function to get motors going in either CW, CCW, BRAKEVCC, or 
 BRAKEGND. Use motorOff(int motor) to turn a specific motor off.
 
 The motor variable in each function should be either a 0 or a 1.
 pwm in the motorGo function should be a value between 0 and 255.
 */
#define BRAKEVCC 0
#define CW   1
#define CCW  2
#define BRAKEGND 3
#define CS_THRESHOLD 100

/*  VNH2SP30 pin definitions
 xxx[0] controls '1' outputs
 xxx[1] controls '2' outputs */
int inApin[2] = {7, 4};  // INA: Clockwise input
int inBpin[2] = {8, 9}; // INB: Counter-clockwise input
int pwmpin[2] = {5, 6}; // PWM input
int cspin[2] = {2, 3}; // CS: Current sense ANALOG input
int enpin[2] = {0, 1}; // EN: Status of switches output (Analog pin)

int statpin = 13;

void setup()
{
  Serial.begin(9600);
  
  pinMode(statpin, OUTPUT);

  // Initialize digital pins as outputs
  for (int i=0; i<2; i++)
  {
    pinMode(inApin[i], OUTPUT);
    pinMode(inBpin[i], OUTPUT);
    pinMode(pwmpin[i], OUTPUT);
  }
  // Initialize braked
  for (int i=0; i<2; i++)
  {
    digitalWrite(inApin[i], LOW);
    digitalWrite(inBpin[i], LOW);
  }
  // motorGo(0, CW, 1023);
  // motorGo(1, CCW, 1023);
}

void loop()
{
  motorGo(0, CW, 1023);
  motorGo(1, CCW, 1023);
  delay(500);

  motorGo(0, CCW, 1023);
  motorGo(1, CW, 1023);
  delay(500);
  
  if ((analogRead(cspin[0]) < CS_THRESHOLD) && (analogRead(cspin[1]) < CS_THRESHOLD))
    digitalWrite(statpin, HIGH);
}

void motorOff(int motor)
{
  // Initialize braked
  for (int i=0; i<2; i++)
  {
    digitalWrite(inApin[i], LOW);
    digitalWrite(inBpin[i], LOW);
  }
  analogWrite(pwmpin[motor], 0);
}

/* motorGo() will set a motor going in a specific direction
 the motor will continue going in that direction, at that speed
 until told to do otherwise.
 
 motor: this should be either 0 or 1, will selet which of the two
 motors to be controlled
 
 direct: Should be between 0 and 3, with the following result
 0: Brake to VCC
 1: Clockwise
 2: CounterClockwise
 3: Brake to GND
 
 pwm: should be a value between ? and 1023, higher the number, the faster
 it'll go
 */
void motorGo(uint8_t motor, uint8_t direct, uint8_t pwm)
{
  if (motor <= 1)
  {
    if (direct <=4)
    {
      // Set inA[motor]
      if (direct <=1)
        digitalWrite(inApin[motor], HIGH);
      else
        digitalWrite(inApin[motor], LOW);

      // Set inB[motor]
      if ((direct==0)||(direct==2))
        digitalWrite(inBpin[motor], HIGH);
      else
        digitalWrite(inBpin[motor], LOW);

      analogWrite(pwmpin[motor], pwm);
    }
  }
}

Bonjour, un bout de code en Pyton qui tourne Raspberry.

import time
from smbus import SMBus
bus= SMBus(1)   # 1 indique qu'il faut utiliser le port /dev/i2c-1

while True:
    # Le composant porte l'adresse 0x48 (A0 et A1 relies à GND)
    # On va lire plusieurs octets a partir du registre 0
    data = bus.read_i2c_block_data(0x48, 0) 
    
    tempMSB = data[0]
    tempLSB = data[1]
    
    temperature=(((tempMSB << 8) + tempLSB) >>7) * 0.5
    if temperature > 128 :  # test si la temperature est negative
        # complement a 1 de la temperature
        temperature = (((((tempMSB << 8) + tempLSB) >>7 )* 0.5) -256)
            
    print(temperature)
    fichier = open ('fichier_anne_marie','a')
    fichier.write (str(temperature))
    fichier.write (',  ')
    fichier.close () 
    
    time.sleep(2)

pas le mien, mais celui de M. Pascal YON, professeur à l’IUT GEII de l’université de Rennes 1.

Utiliser un capteur LM76, puis aller lire le contenu d’un registre afin de connaître la température.

Merci de la réponse. J'avais déja trouvé des exemples liées aux sondes de temperature mais aucun exemple concret dans le cas d'un piloltage de moteurs via arduino.

Quelqu'un pourrais m'expliquer comment, depuis le raspi, donner l'ordre au slave (l'arduino) de mettre 2 pins (8 et 9 par exemple) à l'état haut et inversemment? Je galère vraiment depuis des jours ..... Merci d'avance

Bonjour,

Tu trouveras un exemple ici: https://github.com/3sigma/GeerosRaspberryPython

Ca fonctionne sur ce robot: http://boutique.3sigma.fr/118-geeros-raspberry-python.html

L'élément clé dans le code Python (https://github.com/3sigma/GeerosRaspberryPython/blob/master/Systeme_B/root/programmes_python/CommandeEnTension.py) se trouve ligne 178: arduino.motors(tension_int_gauche, tension_int_droit)

Ca appelle une fonction qui se trouve dans cet autre programme (ligne 47): https://github.com/3sigma/GeerosRaspberryPython/blob/master/Systeme_B/root/programmes_python/arduino/arduino.py

C'est décodé dans le programme Arduino, ligne 182: https://github.com/3sigma/GeerosRaspberryPython/blob/master/Arduino/Firmware_2/Firmware_2.ino

Ca affecte la tension des moteurs, même programme ligne 158.

Bon courage !

Nicolas

Merci infiniment! Je viens juste de survoler les infos que tu m'as envoyé et ça à vraiment l'air complet. Je ferai un petit retour dès que j'aurai réussi à en faire quelque chose d'intéressant. Merci encore.

Bonjour,
J’ai le même objectif envoyer via i2C des commandes d’un raspberry à un schield sur arduino.
Dans mon cas il s’agit de piloter deux moteurs d’un robot mobile à 2 roues. Si vous êtes dans cette configuration, dans mon cas la solution que je vais tenter est d’utiliser :

data = bus.Write_i2c_block_data(0x48, 0)

VMoteurG = data[0]
VMoteur D = data[1]

Je récupère sur raspberry via bluetooth ou autre une direction et une vitesse pour Moteurs gauche et droit, comme deux roues deux moteurs : je traduit en 1 variable moteur % de puissance max (permet de rester dans octet<256) en positif ou négatif (avant arrière) pour gauche et droit, et je l’envoi sur arduino avec …block_data.

Pour info. je continue à hésiter vers une solution utilisant les ports séries. Si quelqu’un abouti merci de communiquer.