Interruption + DS1307 sur Adrduino Mega

Bonjour à tous,

J'ai choisi la carte Arduino Mega car elle dispose de 6 interruptions (c'est pile le nombre dont j'ai besoin pour mon projet) Tout fonctionne bien.

Dans un 2nd temps, j'ai besoin d'horodaté certaines données. J'ai donc acheter un petit montage à base du DS1307 (https://www.adafruit.com/products/264). Nickel, j'ai maintenant la date et l'heure.

Petit problème ce montage utilise les broche SDA(20) et SCL(21) de la carte Arduino Mega, ces même broches sont aussi utilisées pour les interruptions 2 et 3.

Ma question : peut-on utiliser le DS1307 sur d'autre broches (déporter SDA et SCL) ou attacher les 2 interruptions à d'autres broches ? Est ce quelqu'un à déjà été confronté à ce problème ?

Bonjour

Déporter physiquement SDA et SCL sur d'autres broches n'est pas possible, par contre il existe une librairie "softI2C" permettant de créer, par soft, une autre interface i2C sur des broches quelconques : http://forums.adafruit.com/viewtopic.php?f=25&t=13722 avec des exemples d'utilisation du DS1307 sur ces interfaces I2C'soft'

Merci beaucoup, je regarde ça.

Bonjour,

Il existe une autre librairie i2c software, normalement elle est faite pour le projet blinkM mais je l'utilise sans problème avec des pcf8574, DS1307 & co http://code.google.com/p/blinkm-projects/source/browse/#svn%2Ftrunk%2Fblinkm_examples%2Farduino%2FBlinkMSoftI2CDemo

Super je m'en sort bien. Merci à vous 2! J'ai utiliser le code de al1fch car il y avait un exemple pour le DS1307.

Merci encore

Je viens de découvrir que l’on peut attacher des interruptions sur n’importe quelle broche “par le soft”
http://arduino.cc/playground/Main/PcInt
Je n’ai pas testé, mais si ça peut intéressé qqun …

jmatgou: Je viens de découvrir que l'on peut attacher des interruptions sur n'importe quelle broche "par le soft" http://arduino.cc/playground/Main/PcInt Je n'ai pas testé, mais si ça peut intéressé qqun ...

Pour ceux qui serait intéressé, PCint fonctionne trés bien et sera "peut être" intégré à attachInterrupt dans arduino beta 1.0 (mais pour le moment il reste plein de truc qui devait être fait qui le sont pas même dans la RC2 :~)

… Je viens de tester le programme de l’exemple de PCInt

#include "pins_arduino.h"
/*
 * an extension to the interrupt support for arduino.
 * add pin change interrupts to the external interrupts, giving a way
 * for users to have interrupts drive off of any pin.
 * Refer to avr-gcc header files, arduino source and atmega datasheet.
 */

/*
 * Theory: all IO pins on Atmega168 are covered by Pin Change Interrupts.
 * The PCINT corresponding to the pin must be enabled and masked, and
 * an ISR routine provided.  Since PCINTs are per port, not per pin, the ISR
 * must use some logic to actually implement a per-pin interrupt service.
 */

/* Pin to interrupt map:
 * D0-D7 = PCINT 16-23 = PCIR2 = PD = PCIE2 = pcmsk2
 * D8-D13 = PCINT 0-5 = PCIR0 = PB = PCIE0 = pcmsk0
 * A0-A5 (D14-D19) = PCINT 8-13 = PCIR1 = PC = PCIE1 = pcmsk1
 */

volatile uint8_t *port_to_pcmask[] = {
  &PCMSK0,
  &PCMSK1,
  &PCMSK2
};

static int PCintMode[24];

typedef void (*voidFuncPtr)(void);

volatile static voidFuncPtr PCintFunc[24] = { 
  NULL };

volatile static uint8_t PCintLast[3];

/*
 * attach an interrupt to a specific pin using pin change interrupts.
 */
 void PCattachInterrupt(uint8_t pin, void (*userFunc)(void), int mode) {
  uint8_t bit = digitalPinToBitMask(pin);
  uint8_t port = digitalPinToPort(pin);
  uint8_t slot;
  volatile uint8_t *pcmask;

  // map pin to PCIR register
  if (port == NOT_A_PORT) {
    return;
  } 
  else {
    port -= 2;
    pcmask = port_to_pcmask[port];
  }

// -- Fix by Baziki. In the original sources it was a little bug, which cause analog ports to work incorrectly.
  if (port == 1) {
     slot = port * 8 + (pin - 14);
  }
  else {
     slot = port * 8 + (pin % 8);
  }
// --Fix end
  PCintMode[slot] = mode;
  PCintFunc[slot] = userFunc;
  // set the mask
  *pcmask |= bit;
  // enable the interrupt
  PCICR |= 0x01 << port;
}

void PCdetachInterrupt(uint8_t pin) {
  uint8_t bit = digitalPinToBitMask(pin);
  uint8_t port = digitalPinToPort(pin);
  volatile uint8_t *pcmask;

  // map pin to PCIR register
  if (port == NOT_A_PORT) {
    return;
  } 
  else {
    port -= 2;
    pcmask = port_to_pcmask[port];
  }

  // disable the mask.
  *pcmask &= ~bit;
  // if that's the last one, disable the interrupt.
  if (*pcmask == 0) {
    PCICR &= ~(0x01 << port);
  }
}

// common code for isr handler. "port" is the PCINT number.
// there isn't really a good way to back-map ports and masks to pins.
static void PCint(uint8_t port) {
  uint8_t bit;
  uint8_t curr;
  uint8_t mask;
  uint8_t pin;

  // get the pin states for the indicated port.
  curr = *portInputRegister(port+2);
  mask = curr ^ PCintLast[port];
  PCintLast[port] = curr;
  // mask is pins that have changed. screen out non pcint pins.
  if ((mask &= *port_to_pcmask[port]) == 0) {
    return;
  }
  // mask is pcint pins that have changed.
  for (uint8_t i=0; i < 8; i++) {
    bit = 0x01 << i;
    if (bit & mask) {
      pin = port * 8 + i;
      // Trigger interrupt if mode is CHANGE, or if mode is RISING and
      // the bit is currently high, or if mode is FALLING and bit is low.
      if ((PCintMode[pin] == CHANGE
          || ((PCintMode[pin] == RISING) && (curr & bit))
          || ((PCintMode[pin] == FALLING) && !(curr & bit)))
          && (PCintFunc[pin] != NULL)) {
        PCintFunc[pin]();
      }
    }
  }
}


SIGNAL(PCINT0_vect) {
  PCint(0);
}
SIGNAL(PCINT1_vect) {
  PCint(1);
}
SIGNAL(PCINT2_vect) {
  PCint(2);
}

volatile long ticktocks = 0;
long i = 0;

void tick(void) {
  ticktocks++;
}

void tock(void) {
  ticktocks--;
}

void setup()
{
  Serial.begin(9600);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  delay(3000);
  PCattachInterrupt(4, tick, CHANGE);
  PCattachInterrupt(5, tock, CHANGE);
}

void loop() {
  i++;
  delay(1000);
  Serial.print(i, DEC);
  Serial.print(" ");
  Serial.println(ticktocks);
  if (i > 256) {
    PCdetachInterrupt(4);
    PCdetachInterrupt(5);
  }
}

Je n’arrive pas à le faire fonctionner =(
Je rappelle que j’ai une arduino Mega et un shield Ethernet monté dessus.

Si quelqu’un a déjà réussi à utiliser les interruptions avec PCInt sur d’autres broches que celles normalement prévues, je veux bein qu’il m’explique car je ne comprend pas.

Merci

Bonjour,

Comme j’aime bien avoir les idées claires quand je programme, je me permet de vous poser quelques questions supplémentaires.

I) sur la base de la librairie I2C SoftWare :

skywodd:
Bonjour,
Il existe une autre librairie i2c software, normalement elle est faite pour le projet blinkM mais je l’utilise sans problème avec des pcf8574, DS1307 & co
http://code.google.com/p/blinkm-projects/source/browse/#svn%2Ftrunk%2Fblinkm_examples%2Farduino%2FBlinkMSoftI2CDemo

Dans le programme il faut inclure ces lignes :

#include “SoftI2CMaster.h” // Permet d’intégrer la librairie

const byte sdaPin = 7; // Permet de définir la nouvelle broche SDA
const byte sclPin = 6; // Permet de définir la nouvelle broche CSL

SoftI2CMaster i2c = SoftI2CMaster( sdaPin,sclPin ); // Permet d’envoyer à la librairie les numéros des broches choisies

Et les deux fichiers : SoftI2CMaster.cpp et SoftI2CMaster.cpp doivent être enregistrés dans le répertoire \hardware\arduino\cores\arduino?

Ce qui m’étonne ce sont les balises HTML dans les fichiers de cette librairie???

II) Sur la base de SoftI2cMaster :

al1fch:
Bonjour

Déporter physiquement SDA et SCL sur d’autres broches n’est pas possible, par contre il existe une librairie “softI2C” permettant de créer, par soft, une autre interface i2C sur des broches quelconques :
http://forums.adafruit.com/viewtopic.php?f=25&t=13722
avec des exemples d’utilisation du DS1307 sur ces interfaces I2C’soft’

Dans le programme il faut inclure ces lignes :

#include <SoftI2cMaster.h> // Permet d’intégrer la librairie
#include <TwiMaster.h> /// Obligatoire ???

// select software or hardware i2c ///???
#define USE_SOFT_I2C 1

#if USE_SOFT_I2C

// pins for DS1307 with software i2c
#define SCL_PIN 2 // Permet de définir la nouvelle broche SCL
#define SDA_PIN 3 // Permet de définir la nouvelle broche SDA

// An instance of class for software master
SoftI2cMaster rtc;

Et dans le setup :

void setup(void) ///
{
Serial.begin(9600);
#if USE_SOFT_I2C
// set i2c pins pullups enabled by default
rtc.init(SCL_PIN, SDA_PIN); // c’est ici que l’ont envoie les numéros des broches définies
#else
// true to enable pullups
rtc.init(true);
#endif
// to make sure first Serial line is good not for i2c
delay(1000);
}

Et bien sûr les deux fichiers : SoftI2cMaster.cpp et SoftI2cMaster.cpp doivent être enregistrés dans le répertoire \hardware\arduino\cores\arduino?

Merci par avance pour tous ceux qui prendrons le temps de bien vouloir répondre à mes interrogations.

Cordialement.

Telson:
Et les deux fichiers : SoftI2CMaster.cpp et SoftI2CMaster.cpp doivent être enregistrés dans le répertoire \hardware\arduino\cores\arduino?

Les deux fichiers doivent être placé dans un dossier dans \libraries exemple \libraries\SoftI2C (ou n’importe quelle autre nom de dossier n’existant pas déja).
Aucun fichier ne doit être placé dans \hardware\arduino\cores\arduino, c’est un emplacement réservé exclusivement aux “routines” de fonctionnement arduino (digitalWrite, …).

Telson:
Ce qui m’étonne ce sont les balises HTML dans les fichiers de cette librairie???

Hein!? Qu’est ce que tu appelle “balises HTML” !!? Il n’y a aucune balise HTML dans le code source de la librairie …

Telson:
#include <SoftI2cMaster.h> // Permet d’intégrer la librairie
#include <TwiMaster.h> /// Obligatoire ??? OUI, c’est une classe virtuelle qui permet de travailler avec de l’I2C hardware ou software via un simple define

// select software or hardware i2c ///??? Define qui se trouve ici, si #define USE_SOFT_I2C 1 est présent on utilise la version “software” I2C sinon l’I2C normal comme avec Wire.

#define USE_SOFT_I2C 1

#if USE_SOFT_I2C

// pins for DS1307 with software i2c
#define SCL_PIN 2 // Permet de définir la nouvelle broche SCL
#define SDA_PIN 3 // Permet de définir la nouvelle broche SDA // Et justement comme USE_SOFT_I2C est défini on peut choisir les broches SDA et SCL

// An instance of class for software master
SoftI2cMaster rtc;

Et dans le setup :

void setup(void) ///C’est quoi ce void dans les paranthèses??? void setup() ou void setup(void) veulent dire la exactement même chose, c’est une fonction sans paramètres
{
Serial.begin(9600);
#if USE_SOFT_I2C
// set i2c pins pullups enabled by default
rtc.init(SCL_PIN, SDA_PIN); // c’est ici que l’ont envoie les numéros des broches définies
#else
// true to enable pullups // On remarque ici que suivant si on utilise l’I2C hardware ou software la fonction init() n’as pas la même syntaxe
rtc.init(true);
#endif
// to make sure first Serial line is good not for i2c
delay(1000);
}

Telson:
Et bien sûr les deux fichiers : SoftI2cMaster.cpp et SoftI2cMaster.cpp doivent être enregistrés dans le répertoire \hardware\arduino\cores\arduino?

Même réponse que pour la question (1).

Bonjour,

En ce qui concerne les balises HTML................Heu.....Désolé, je ne sais pas ce que j'ai fait mais c'est du grand n'imp!!!

Par contre, en ce qui concerne les libraires pour gérer le temps le lien : http://arduino.cc/playground/Code/Time, est parfait.

Merci.