Aidez nous ! Projet - Gestion domotique

#include 
#include 
#include 

#define DATA_LENGTH 6
#define ADDRESS 0x10
#define RECEIVER 0x11
#define RE_DE_ON PORTD|=4
#define RE_DE_OFF PORTD&=~(4)
#define RE_DE_REG DDRD |= 4
#define BAUD 115200

#define _WAIT(_pres) _delay_us(_pres)
#define SERIAL_BUFFER_SIZE 16

struct ring_buffer
{
  uint8_t buffer[SERIAL_BUFFER_SIZE];
  volatile uint8_t head;
  volatile uint8_t tail;
};

volatile uint8_t listener = 0;
volatile uint32_t delayWD = 0;
ring_buffer rx_buffer  =  { { 0 }, 0, 0 };

uint8_t bufferBusTx[DATA_LENGTH] = {0}; 

uint32_t delayS = 0;
uint32_t _micros = 0;

volatile uint8_t ack = 0;
uint8_t err = 0;

const uint32_t pres = 69120000/BAUD; //temps de maintien RE_DE
const uint32_t maxRec = 14000000/BAUD; //temps max en reception
const uint32_t maxTrans = (32640000/(BAUD/100))+((ADDRESS*(pres*2))); //temps max de transaction+ temps different entre module selon l'adresse

volatile uint8_t* registreR[3] = {&PINB, &PINC, &PIND}; //tableau pour la gestion semi dynamique des registres (&DDR = &PIN+1, &P0RT= &PIN+2)

uint8_t stateB = 0;
uint32_t delayB = 0;

inline void store_char(uint8_t c, struct ring_buffer *buffer) //gestion des donnees entrantent dans le buffer (circulaire)
{
  uint8_t i = (uint8_t)(buffer->head + 1) % SERIAL_BUFFER_SIZE;

  if (i != buffer->tail) {
    buffer->buffer[buffer->head] = c;
    buffer->head = i;
  }
}

ISR(USART_RX_vect)
{
  if((UCSR0B & (1<= delayB) // code de teste en temps que contrôleur distant, remplissage du buffer
  {
      if(!stateB)
      {
        bufferBusTx[0] = 0x05; //taille des donnees
        bufferBusTx[1] = RECEIVER; //destinataire
        bufferBusTx[2] = ADDRESS; //emeteur
        bufferBusTx[3] = 0x01; //cmd
        bufferBusTx[4] = 0x02;  //param: registre
        bufferBusTx[5] = 0x20; // param: bit

      }
      else
      { 
        bufferBusTx[0] = 0x05;
        bufferBusTx[1] = RECEIVER;
        bufferBusTx[2] = ADDRESS;
        bufferBusTx[3] = 0x00;
        bufferBusTx[4] = 0x02;
        bufferBusTx[5] = 0x20;
      } 
      delayB = _micros+250000;
  }
  
  if(listener != 0) //debug
  {
    PORTD |= 8;
  }
  else
  {
    PORTD &= ~(8);
  }
  PORTB &= ~(56);// debug
  PORTD &= ~(31);//debug
}

uint8_t sendData()
{
  if(bufferBusTx[2] && !listener) // si données à transmettre et que le bus est libre (=0)
  {
    PORTB |= 8; //debug
    _WAIT(pres); //petite pause de sécurité car même en cas de liberation '0', RE_DE peux encore être maintenu de l'autre côté
    writeData(bufferBusTx); //on envois les données
    ack = 1; //
  }
  
  if(listener && _micros >= delayWD) // si delay de transaction max est dépasse donc erreur, collision, etc
  {
    listener = 0x00;
    ack = 0;
  }
}

void readData() // reception
{
    if(read() == 0x02) //debut de trame
    {
      delayS = _micros+(maxRec*2); //definition d'un delay max pour la lecture 
      while(!available()) //temps qu'il n'y a pas de suite ...
      {
        if(micros() >= delayS) // si delay depasse on arrête et on retourne une erreur
        {
          PORTD |= 16;
          ackError(0x01);
          break;
        }
      } 

      uint8_t sizeD = read(); // recuperation de la taille des donnees
      uint8_t data[sizeD+4];
      data[0] = sizeD;
      delayS = _micros+(maxRec*(sizeD+4)); //definition d'un delay max pour la lecture
      
      uint8_t i = 1;
      while(i < data[0]+4) //temps qu'on a pas reçu toute la trame
      {
        if(micros() >= delayS) // si delay depasse on arrête et on retourne une erreur
        {
          PORTD |= 16;
          ackError(0x01);
          break;
        }
        
        if(available()) // si donnée(s)
        {
          data[i] = read();
          ++i;
        }
      }

      if(data[data[0]+3] == 0x03) //fin de trame
      {
        if(checkData(data)) //crc ok, on envoie la commande
        {
          action(data, 0);
        }
        else //sinon on retourne directement un message d'erreur crc à l'envoyeur
        {
          ackError(0x02);
        }
      }
      else //sinon on retourne directement un message d'erreur general de reception
      {
        (0x01);
      }
    }
    RXflush();   
}

void action(uint8_t* data, uint8_t local)
{
  if(data[3] < 0xFE) //s'il sagit d'une cmd
  {
    if(data[3]==0x00) // test off
    {
      *(registreR[data[4]]+2) &= ~(data[5]); //PORT &= ~(bit)
    }
    else if(data[3]==0x01) //test on
    {
      *(registreR[data[4]]+2) |= data[5];
    }
    
    data[5] = ((*registreR[data[4]])&(data[5])); // pour ack : PIN&BIT
    
    if(local) //s'il sagit d'une commande local on rempli le buffer de transmition
    {
      bufferBusTx[0] = 0x05;
      bufferBusTx[1] = 0x80;
      bufferBusTx[2] = ADDRESS;
      bufferBusTx[3] = 0xFD;
      bufferBusTx[4] = data[4];
      bufferBusTx[5] = data[5];
    }
    else //sinon on retourne directement un ack de confirmation 
    {
      data[1] = 0x80;
      data[2] = ADDRESS;
      data[3] = 0xFF;
      _WAIT(pres);
      writeData(data); 
    } 
  }
  
  if(ack && data[3] >= 0xFE && (bufferBusTx[1] == data[2])) //si transaction en cours et cmd >= FE
  {
    if(data[3] == 0xFF || err == 2) // ack positif ou plus de 3 échec, on libère le bus
    {
      bufferBusTx[2] = 0;
      _WAIT(pres);
      RE_DE_ON;
      write(0x00, 1);
      _WAIT(pres);
      RE_DE_OFF;
      ack = 0;
      err = 0;
      if(data[3] == 0xFF) //s'il sagit d'un ack positif on enregistre le resultat
      {
        stateB = data[5];
      }
    }    
    else //si un ack d'erreur on retante directement
    {
      ++err;
      _WAIT(pres);
      writeData(bufferBusTx);
    }
  }
}

void writeData(uint8_t* data)
{
  //calcul du crc en premier
  uint16_t crc = 0xFFFF;
  
  for(uint8_t i=0; i <= data[0]; i++)
  {
    crc = _crc16_update(crc, data[i]);
  }
  
  //active le mode transmition
  RE_DE_ON;
  
  write(data[1], 1); //adressage
  write(0x02, 0); //debut de trame
  for(uint8_t i=0; i <= data[0]; i++) //donnees (suivant la taille specifiée)
  {
    write(data[i], 0);
  }
  
  write(((crc & 0xFF00) >> 8), 0); //crc MSB
  write((crc & 0x00FF), 0); //crc LSB
  write(0x03, 0); //fin de trame
  _WAIT(pres); //delay de maintien 
  RE_DE_OFF; // on desacive le mode de transmition
}

uint8_t checkData(uint8_t* data) //controle crc
{
  uint16_t crc = 0xFFFF;
  uint16_t _crc = (data[data[0]+1]<<8);
  _crc += data[data[0]+2];
  for(uint8_t i=0; i <= data[0]; i++)
  {
    crc = _crc16_update(crc, data[i]);
  }
  
  if(crc == _crc)
  {
    return 1;
  }
  
  return 0;
}

void ackError(uint8_t ErrorNo)
{
  uint8_t data[5] = {0};
  data[0] = 0x04; 
  data[1] = 0x81;
  data[2] = ADDRESS;
  data[3] = 0xFE;
  data[4] = ErrorNo;
  _WAIT(pres);
  writeData(data);
}
//////////////////////////////////////////////////////////////////////////////////////////////////

void write(uint8_t data, uint8_t txb8)
{
  while (!((UCSR0A) & (1 << UDRE0)))
    ; 
  if(txb8)
  {
    UCSR0B |= (1<> 8;
  UBRR0L = baud_setting;
    
  UCSR0B = (1<

Com poste suivant:

Suite: Histoire de montré où j'en suis dans mes tests je met mon code brouillons actuel avec quelque commentaires. Comme c'est là chaque module est contrôleur et récepteur en même temps (pour le brouillons), il n'y a pas de maître du bus, la gestion des collision , erreurs, etc se fait par des délais. Les délais doivent encore être mieux réglé et défini d'après la longeur max d'une trame (je pense mettre à 32 max). Tout fonctionne correctement avec trois arduino mini contrôleur et récepteur en même temps, tout les trois tester dans les deux modes simultanément :astonished: (au final ça sera pas ainsi mais là c'est le stress test :grin:), avec des transactions de plus ou moin 50ms à 9600baut et 4ms à 115200baut pour une trame de 10 octet (commande simple sur registre I/O).

Il y a encore du boulot mais le plus gros est fait je pense, si quelqu'un a des idées, suggestions ou questions ? :sweat_smile: :*

Yep!

Super, j'ai commencé à regarder ton code XD Je pense partir sur quelque chose de plus épuré dans un premier temps, on voit que tu as bien appronfondi le sujet ;)

J'ai pourtant deux questions qui me passe là :

First, quelle est la taille (utilisation mem) de la bibliothèque crc16 ??? Second, pourquoi avoir utilisé un watchdog ? On risque pas le reset complet du programme ?? Alternative : timer, interruption ???

J'ai reçu il y a peu mes SN75176 et quelques tiny2313, si l'on part sur des commandes simples avec retour vers le maitre par echo, je pense qu'il faudra parier sur un uC plus simpliste que le 328 ou 644 (dip')

@+

Zoroastre.

zoroastre: J'ai pourtant deux questions qui me passe là :

First, quelle est la taille (utilisation mem) de la bibliothèque crc16 ??? Second, pourquoi avoir utilisé un watchdog ? On risque pas le reset complet du programme ?? Alternative : timer, interruption ???

pour la taille de la biblio crc16 (de la lib avr) je sais pas trop mais je ferais le teste une fois , pour l'instant le tout pèse +- 2,5ko en mémoire programme (donc avec les 450octet rajouter pas le core arduino et les divers chose utile pour debug, etc ). Le watchdog pour l'instant c'est juste dans mes testes brouillons, je découvre. :grin:, mais j'ai fais au maximum pour ne pas avoir de code bloquant comme pour la partie envoi "sendData();" juste au passage dans loop ou le timer "delayS" (boucle sécurisée) à la réception par ex.

zoroastre: J'ai reçu il y a peu mes SN75176 et quelques tiny2313, si l'on part sur des commandes simples avec retour vers le maitre par echo, je pense qu'il faudra parier sur un uC plus simpliste que le 328 ou 644 (dip')

J'utilise les mini (168) pour l'instant comme c'était le plus minimaliste et simple pour moi qui suis amateur dans le domaine des uC et l'électronique en général :sweat_smile:, mais les ATtiny m’intéresse donc s'il y a moyen de faire encore plus minimaliste (conso, taille, etc) je reste ouvert à toute propositions (et surtout aide :grin:) :open_mouth: Enfin pour l'instant ça reste du prototypage. ;)

Yop yop, Ai fais le test pour la fonction de la lib crc16 et elle pèse 52octet en mémoire programme.

J'ai également testé et adapté le code pour un module version tiny et j’obtiens 1388 octet, pas testé mais fonctionnel sur mini (1684octet) .

#include 
#include 
#include 

#define DATA_LENGTH 6
#define ADDRESS 0x11
#define RECEIVER 0x12
#define RE_DE_ON PORTD|=4
#define RE_DE_OFF PORTD&=~(4)
#define RE_DE_REG DDRD |= 4
#define BAUD 115200

#define _WAIT(_pres) _delay_us(_pres)

#define SERIAL_BUFFER_SIZE 10
volatile uint8_t pos = 0;
volatile uint8_t bufferBusRx[SERIAL_BUFFER_SIZE];

volatile uint8_t listener = 0;
volatile uint32_t delayWD = 0;

uint8_t bufferBusTx[DATA_LENGTH] = {0}; 

volatile uint8_t ack = 0;
uint8_t err = 0;

const uint32_t pres = 69120000/BAUD; //temps de maintien RE_DE
const uint32_t maxRec = 14000000/BAUD; //temps max en reception
const uint32_t maxTrans = (32640000/(BAUD/100))+((ADDRESS*(pres*2))); //temps max de transaction+ temps different entre module selon l'adresse

volatile uint8_t* registreR[3] = {&PINA, &PINB, &PIND}; //tableau pour la gestion semi dynamique des registres (&DDR = &PIN+1, &P0RT= &PIN+2)

uint8_t stateB = 0;
uint32_t delayB = 0;

ISR(USART_RX_vect)
{
  if((UCSRB & (1<= delayWD) // si delay de transaction max est dépasse donc erreur, collision, etc
  {
    listener = 0x00;
    ack = 0;
  }
}

void readData() // reception
{
    if(bufferBusRx[0] == 0x02 && bufferBusRx[9] == 0x03) //debut de trame
    {
        if(checkData()) //crc ok, on envoie la commande
        {
          action(0);
        }
        else //sinon on retourne directement un message d'erreur crc à l'envoyeur
        {
          
          ackError(0x02);
        }
    }
    else //sinon on retourne directement un message d'erreur general de reception
    {
      ackError(0x01);
    }
     
}

void action(uint8_t local)
{
    if(bufferBusRx[4]==0x00) // test off
    {
      *(registreR[bufferBusRx[5]]+2) &= ~(bufferBusRx[6]); //PORT &= ~(bit)
    }
    else if(bufferBusRx[4]==0x01) //test on
    {
      *(registreR[bufferBusRx[5]]+2) |= bufferBusRx[6];
    }
    
    uint8_t val = ((*registreR[bufferBusRx[5]])&(bufferBusRx[6])); // pour ack : PIN&BIT
    
    if(local) //s'il sagit d'une commande local on rempli le buffer de transmition
    {
      bufferBusTx[0] = 0x05;
      bufferBusTx[1] = 0x80;
      bufferBusTx[2] = ADDRESS;
      bufferBusTx[3] = 0xFD;
      bufferBusTx[4] = bufferBusRx[5];
      bufferBusTx[5] = val;
    }
    else //sinon on retourne directement un ack de confirmation 
    {
      uint8_t data[6];
      
      data[0] = 0x05;
      data[1] = 0x80;
      data[2] = ADDRESS;
      data[3] = 0xFF;
      data[4] = bufferBusRx[5];
      data[5] = val;
      _WAIT(pres);
      writeData(data); 
    } 
}

void writeData(uint8_t* data)
{
  //calcul du crc en premier
  uint16_t crc = 0xFFFF;
  
  for(uint8_t i=0; i <= data[0]; i++)
  {
    crc = _crc16_update(crc, data[i]);
  }
  
  //active le mode transmition
  RE_DE_ON;
  
  write(data[1], 1); //adressage
  write(0x02, 0); //debut de trame
  for(uint8_t i=0; i <= data[0]; i++) //donnees (suivant la taille specifiée)
  {
    write(data[i], 0);
  }
  
  write(((crc & 0xFF00) >> 8), 0); //crc MSB
  write((crc & 0x00FF), 0); //crc LSB
  write(0x03, 0); //fin de trame
  _WAIT(pres); //delay de maintien 
  RE_DE_OFF; // on desacive le mode de transmition
}

uint8_t checkData() //controle crc
{
  uint16_t crc = 0xFFFF;
  
  uint16_t _crc = (bufferBusRx[7]<<8);
  _crc += bufferBusRx[8];
  
  for(uint8_t i=1; i <= bufferBusRx[1]+1; i++)
  {
    crc = _crc16_update(crc, bufferBusRx[i]);    
  }

  if(crc == _crc)
  {
    return 1;
  }
  
  return 0;
}

void ackError(uint8_t ErrorNo)
{
  uint8_t data[5] = {0};
  data[0] = 0x04; 
  data[1] = 0x81;
  data[2] = ADDRESS;
  data[3] = 0xFE;
  data[4] = ErrorNo;
  _WAIT(pres);
  writeData(data);
}


void write(uint8_t data, uint8_t txb8)
{
  while (!((UCSRA) & (1 << UDRE)))
    ; 
  if(txb8)
  {
    UCSRB |= (1<> 8;
  UBRRL = baud_setting;
    
  UCSRB = (1<

Yep!

1418 octets pour un tiny2313 (8Mhz). Le transfert Isp se déroule correctement ;)

Par contre, je ne peux pas tester plus avant le code, mon uC est sur un proto de 5x3 cm pour effectuer des tests Pwm pour le taff. Je suis en train de dessiner sur kicad un autre proto avec 1 Atmega644, 1 ou 2 Attiny2313, des SN75176, I2C et SPI. J'ai besoin d'experimenter les conversations sur plusieurs protocoles, principalement sur l'I2C car je compte m'inspirer des automates modernes (1 tache rapide + 1 tache lente) pour créer un carte biproc à base d'ATmega644.

Merci pour ton code trés bien écrit, il me sera certainement utile ;)

Tu en es où de tes experimentations du Rs485 sur le terrain ?

@+

Zoroastre.

Yop yop, sorry pour la réponse tardive je me choppe une petite grippe depuis hier. =(

zoroastre: J'ai besoin d'experimenter les conversations sur plusieurs protocoles, principalement sur l'I2C car je compte m'inspirer des automates modernes (1 tache rapide + 1 tache lente) pour créer un carte biproc à base d'ATmega644.

J'aimerai connaître le résultat de tes expérimentations :open_mouth:, compte rendu obligatoire :grin:.

zoroastre: Merci pour ton code trés bien écrit, il me sera certainement utile ;)

C'est encore un peux brouillon mais je m'approche de la solution final.

zoroastre: Tu en es où de tes experimentations du Rs485 sur le terrain ?

Je suis retourné en half duplex classique, comme ici la communication ne peut être simultanée de toute façons. Par contre toujours en breadboard et bout de fils pendents :*, pas encore testé sur longue distance ou autre, il serait temps que je m'offre un petit fer et composants standard tel que trans, condo, diode, moc, etc, pour aller plus loin.

Par contre tu pourras peut être me renseigné sur la réel différence entre les tiny et atmega, avantage, inconvénient ? Par exemple ici j'aimerais des module simple e/s, 8 entrées (commande locale par bp ou autre) et 8 sorties correspondante (1 en + pour le bus ce qui fait 17 e/s) donc théoriquement avec mes mini 168 (23 I/O - (2 pour l'uart) - (2 crystal)) ça devrait aller ? En fait dans les descriptions première des µc je vois 20 I/O (attiny 2313) par exemple (youpie), sauf que 2 pour l'uart, 2 pour le chrystal, etc ... et donc je n'arrive pas à faire au plus juste (ni trop, ni trop peux) ?

J'ai modifier l'image histoire de voir la correspondance registre et non arduino, il n'y a que le bit7 du registre C (pc7 ?) que je ne trouve pas dans le sommaire de la doc.

Entre () je comprend un peux mieux la team arduino d'avoir fais des tableaux de correspondance afin d'avoir un ordre plus "naturel" et instinctif de correspondance pin/registre vu que certain ne comprennent pas automatiquement 8 bit ou utilisé par l'orloge, l'uart, etc, ... Pour cette dernière raison je vais abandonné la trame cmd/registre/bit mais plutôt dcmd/sortie_n° .

Yep!

osaka: Par contre tu pourras peut être me renseigné sur la réel différence entre les tiny et atmega, avantage, inconvénient ?

ATtiny2313, 2048 bytes, DIP20 ATtiny4313, 4096 bytes, DIP20 ATTiny25/45/85 2048, 4096, 8168 bytes, DIP8

Cà c'est pour ceux que je connais. Il y a aussi des modèles CAN bus.

Naturellement, on ne retrouvera pas toutes les fonctionnalités des mega, principalement du côté des ports analogiques, sur les tiny, je n'en connais pas. L'I2C est aussi sacrifié, mais il demeure le TWI, avec donc, des possibilité quand même. Pour le tiny2313, 18 i/o brutes dont Rx/Tx, 4 Pwm, l'horloge, etc. Quand on fait les comptes, il demeure grosso modo 10/12 i/o. C'est déjà pas mal.

Le principal inconvénient, c'est bien entendu l'absence de port analogique. Pour inclure des capteurs de cette famille, pas le choix faut serialiser à travers un chip ou bidouillé sur les temps de charge/decharge d'une capa.

En ce qui concerne les tiny25/45/85, peut de i/o à la base mais on peut compenser avec des shifts register.

osaka: J'aimerai connaître le résultat de tes expérimentations , compte rendu obligatoire

Pas de souci, par contre faudra être patient, j'ai un truc sur le feu pour l'instant XD

Pour détailler un peu, je compte mettre un afficheur tactile et l'ethernet sur un chip mega644 (taches lentes), quant au second 644, les tâches courantes, gestion des évenements capteurs et envoie des commandes asservies. Le tout en intercommunication. J'espère avec cette configuration obtenir plus de réactivité sur les interfaces IHM. Le protocole I2C est utilisé dans des projets tels que core2duino ou core3duino.

Je n'ai pas encore fixé mon choix sur le chip des modules de commandes, l'attiny2313 a ma préference pour l'instant, mais il va falloir que je m'affranchisse de l'analogique et que je palie ce problème.

Je suis plutôt satisfait de ma solution actuelle à base de mega1280 + afficheur tactile + ds18b20 + relais piloté en rs485. Je crains pourtant en ajoutant l'ethernet et des sondes supplémentaires d'être rapidement saturé en i/o et en vitesse de calcul. Les avantages que j'entrevois dans ma solution est d'obtenir théoriquement deux fois plus d'entrée/sortie avec la même taille mémoire. (robotique ???) Le plus chaud sera de partager les tâches équitablement. (l'option du clustering n'est pas loin!)

L'idée de déporter les modules de commandes me plait de plus en plus ;)

@+

Zoroastre.

Merci, je vois mieux la différence entre les deux maintenant.

zoroastre:

osaka: J'aimerai connaître le résultat de tes expérimentations , compte rendu obligatoire

Pas de souci, par contre faudra être patient, j'ai un truc sur le feu pour l'instant XD

Pour détailler un peu, je compte mettre un afficheur tactile et l'ethernet sur un chip mega644 (taches lentes), quant au second 644, les tâches courantes, gestion des évenements capteurs et envoie des commandes asservies. Le tout en intercommunication. J'espère avec cette configuration obtenir plus de réactivité sur les interfaces IHM.

figure toi que si j'ai bien compris, c'est exactement ce à quoi je pense, séparé contrôleur IHM (affichage, eth, ...) et contrôleur événementiel (temp, lum, horaire, ...) (C'est pour celà que j'ai une adresse spécifique contrôleurs" 0x80" pour les retour et ack des modules, si cette adresse spécifiée, tout les contrôleur écoute c'est qu'il s'agit d'un retour d'état que la commande soit distante ou locale au module).

zoroastre: Je n'ai pas encore fixé mon choix sur le chip des modules de commandes, l'attiny2313 a ma préference pour l'instant, mais il va falloir que je m'affranchisse de l'analogique et que je palie ce problème.

Je suis plutôt satisfait de ma solution actuelle à base de mega1280 + afficheur tactile + ds18b20 + relais piloté en rs485. Je crains pourtant en ajoutant l'ethernet et des sondes supplémentaires d'être rapidement saturé en i/o et en vitesse de calcul. Les avantages que j'entrevois dans ma solution est d'obtenir théoriquement deux fois plus d'entrée/sortie avec la même taille mémoire. (robotique ???) Le plus chaud sera de partager les tâches équitablement. (l'option du clustering n'est pas loin!)

L'idée de déporter les modules de commandes me plait de plus en plus ;)

La conception modulaire me conforte dans l'idée de n'avoir presque aucune limites. :open_mouth:

Yep!

osaka: figure toi que si j'ai bien compris, c'est exactement ce à quoi je pense, séparé contrôleur IHM (affichage, eth, ...) et contrôleur événementiel (temp, lum, horaire, ...)

Ouép, on travaille dans la même direction. C'est aussi une des raisons pour lesquels, je m'interesse beaucoup à tes dernières experimentations ;)

Le protocole I2C est donné pour être plus rapide (100 à 400 khz) que le rs485, certes sur une distance beaucoup beaucoup moins importante. Mais l'essentiel est que ce sont tout deux des protocoles solides avec chacun une mission, celle au voisinage, celle au lointain.

Le proto que je dessine en ce moment réunit la puissance de 2 atmega644 afin de résoudre la séquentialisation des données. En effet, comment donner la priorité à tel ou tel tâche si le cerveau est unique, l'algorithme devient complexe. Si on décuple les cerveaux et on leur attribuent des tâches spécifiques mais conjointent, on commence à parler buffer de process, pipe et on aboutit à un système neuronal proche du clustering, avec un algorithme plus simple, un algorithme de fourmie travailleuse. ;)

@+

Zoroastre.

Yop yop, J'avais pensé à l'I2C (même au spi, can, ...), mais quelque chose me dérangeais c'est la communication maitre esclaves, pour laisser la parole à chaque esclave il est obligé de les interrogé l'un à la suite de l'autre, c'est un peux faire du "token ring" ? J'ai vu qu'il y avait moyen de faire du multi-maître et d'entamé une conversation et transaction à la libération de la ligne sur sdl et sca ? Enfin finalement je me suis dit que j'allais le réservé pour d'autre choses (par ex: le module rtc 1307, ...), que le rs485 permettait la longue distance, le "Multi-processor Communication Mode" que j'avais envie de testouiller, etc , donc j'ai pas approfondi le bus i2c. (et donc ça tombe bien que tu t'y intéresses :grin:). Concernant la vitesse tout dépend également de ses exigences (à 4ms la transaction ça me donne quand même 250 transaction par sec ) et du code qui traine derrière , comme j'ai eu le cas avec l'ethernet (pourtant à 10Mbps théorique) et les sockets, on pourrais ce dire que ça rox, be finalement les différents chipotages,traitements (byte->json, etc) et intermédiaires (php qui clôture la transaction à la simple vue d'un 0 ]:) ) donnent un résultat catastrophique comparé à ce que j’espérais pour une tel vitesse. (enfin ici c'est les différents chipotage pour rendre le tout compatible qui fout le boxon, faudrait que je remette mon shield, j'ai quelques idée pour pallier ça qui me trotte en tête). =( Dans tout les cas la seule façon d'avoir le meilleur choix c'est de testé et comparé (je compte sur toi :grin:). Ca me fait pensé qu'il faudrait testé ma solution sans la gestion du crc voir si ça en vaut la peine ?

zoroastre: Le proto que je dessine en ce moment réunit la puissance de 2 atmega644 afin de résoudre la séquentialisation des données. En effet, comment donner la priorité à tel ou tel tâche si le cerveau est unique, l'algorithme devient complexe. Si on décuple les cerveaux et on leur attribuent des tâches spécifiques mais conjointent, on commence à parler buffer de process, pipe et on aboutit à un système neuronal proche du clustering, avec un algorithme plus simple, un algorithme de fourmie travailleuse. ;)

On peux ajouter que la mort ou destruction d'un neurone n'empêche pas le cerveau de fonctionné (Je n'y vois que des avantages quand je lis ta description). :open_mouth:

zoroastre: un algorithme de fourmie travailleuse

Tien ça me donne idée de nom (s'il faut le nommé :P) au système, "antsDomo" la fourmilière au service de votre maison. XD

Premier post pour vous dire... ... .. . que vous êtes de grands malades! XD

Continuez, personnellement je suis vos avancées avec attention! ;)

Yep!

osaka: J'avais pensé à l'I2C (même au spi, can, ...), ... J'ai vu qu'il y avait moyen de faire du multi-maître et d'entamé une conversation et transaction à la libération de la ligne sur sdl et sca ?

Je suis passé par ces étapes de reflexion également, et effectivement le mode multi-maitre fait partie du protocole I2C. Lors de mes recherches, j'ai entrevus quelques solutions arduino et je pense sincèrement que cela est possible. Les ressources ne sont pourtant pas trés nombreuses et plutôt légères. Il n'y aura, bien sûr, que la pratique qui pourra valider ou pas mes hypothèses. L'experience me tente fortement.

osaka: Ca me fait pensé qu'il faudrait testé ma solution sans la gestion du crc voir si ça en vaut la peine ?

Je m'attendais à ce que le crc soit plus lourd en fait. J'avais regardé les differents algo de contrôle et certain me semblait fort alambiqué. Il faut effectivement voir ce qu'il apporte réellement.

osaka: "antsDomo"

:grin:

Pour le proto, la mise en place des composants ne sera pas trop compliqué, j'ai surtout des problèmes d'esthétique en fait, je travaille sur une seule couche (compo dips uniquement) et j'essaie d'eviter autant que possible les straps. Je suis déjà à mon second shema, le premier sur un seul plan, le second sur deux (principe du shield). Je vais encore tatillonner quelques jours/semaines avant de choisir une solution. J'ai déjà l'essentiel des composants, et j'aimerais autant que possible que le proto soit plus qu'un proto, donc une plateforme pre et/ou définitive. Le processeur IHM sera donc pourvu de l'ethernet de facto (ENC28J), d'un bus rs232 et rs485. Le processeur evenementiel sera doté de deux bus rs485. Une liaison I2C liera les deux processeurs, une eeprom au milieu.

Je travaille depuis peu avec les registres, cette méthode me parle plus en fait, je suis technicien de maintenance et l'automatisme est mon dada. J'ai par contre tout à apprendre du c++, mais je voyage depuis quelques années d'un language à un autre au grés de mes besoins.

Levaillant: vous êtes de grands malades!

Et c'est que le début XD

@+

Zoroastre.

zoroastre:

osaka: Ca me fait pensé qu'il faudrait testé ma solution sans la gestion du crc voir si ça en vaut la peine ?

Je m'attendais à ce que le crc soit plus lourd en fait. J'avais regardé les differents algo de contrôle et certain me semblait fort alambiqué. Il faut effectivement voir ce qu'il apporte réellement.

Je m'attendais également à une certaine lourdeur, jusqu'a ce que je tombe lors d'une de mes explorations sur le crc16.h de la lib avr.

static __inline__ uint16_t
_crc16_update(uint16_t __crc, uint8_t __data)
{
    uint8_t __tmp;
    uint16_t __ret;

    __asm__ __volatile__ (
        "eor %A0,%2" "\n\t"
        "mov %1,%A0" "\n\t"
        "swap %1" "\n\t"
        "eor %1,%A0" "\n\t"
        "mov __tmp_reg__,%1" "\n\t"
        "lsr %1" "\n\t"
        "lsr %1" "\n\t"
        "eor %1,__tmp_reg__" "\n\t"
        "mov __tmp_reg__,%1" "\n\t"
        "lsr %1" "\n\t"
        "eor %1,__tmp_reg__" "\n\t"
        "andi %1,0x07" "\n\t"
        "mov __tmp_reg__,%A0" "\n\t"
        "mov %A0,%B0" "\n\t"
        "lsr %1" "\n\t"
        "ror __tmp_reg__" "\n\t"
        "ror %1" "\n\t"
        "mov %B0,__tmp_reg__" "\n\t"
        "eor %A0,%1" "\n\t"
        "lsr __tmp_reg__" "\n\t"
        "ror %1" "\n\t"
        "eor %B0,__tmp_reg__" "\n\t"
        "eor %A0,%1"
        : "=r" (__ret), "=d" (__tmp)
        : "r" (__data), "0" (__crc)
        : "r0"
    );
    return __ret;
}

Ca m'étonne d'ailleurs que ce code ne soit pas plus utilisé, pour le 1wire par exemple ... alors que ...

_crc_ibutton_update(uint8_t __crc, uint8_t __data)

zoroastre: Pour le proto, la mise en place des composants ne sera pas trop compliqué, j'ai surtout des problèmes d'esthétique en fait, je travaille sur une seule couche (compo dips uniquement) et j'essaie d'eviter autant que possible les straps. Je suis déjà à mon second shema, le premier sur un seul plan, le second sur deux (principe du shield).

Pour le module I/O (8/8) je partais sur le principe du 2 couche (shield mais avec mini qui vient ce "broché" par dessus) vu ça taille (30X17) , sinon pour les autre où le mini ne serait pas adapté ça sera comme toi simple couche et dip ,pas question de uno, mega, ... ou la place est loin d'être optimisé à l'utilisation qu'on en ferais (je suppose que c'est également ton but, d'ailleurs il y a des chance que je te copie :grin:) .

zoroastre: Je travaille depuis peu avec les registres, cette méthode me parle plus en fait, je suis technicien de maintenance et l'automatisme est mon dada. J'ai par contre tout à apprendre du c++, mais je voyage depuis quelques années d'un language à un autre au grés de mes besoins.

En effet la logique semble plus intuitive pour quelqu'un ayant l'habitude de l'automatisme, l'electropneumatique, hydrau, etc, industrielle. Mes premières études (secondaire = college/lycees) étaient dans l'électromécanique (tout du moin avant que je me fasse mettre à la porte de l'école :.), puis la construction mécanique et métallique et mon meilleur amis qui étais avec moi au cours est technicien de maintenance maintenant (kraft be). Finalement je regrette d'avoir choisie la voie de l'informatique (dev) ... Enfin cette voie je l'ai pas vraiment choisie , c'est suite à une reconversion (graduat= bac+3) après une accident de tuture qui ma foutu les bras en l'air. Maintenant j'hésite à faire une "petite" formation d'automaticien ou électromécanicien pour quitté le monde des fauteuils de bureau qui ne veulent pas de moi de toute façons. :grin: Pour l'instant je me réfugie sur les µc et la domo des fourmis.

Levaillant: vous êtes de grands malades!

C'est pas le début de la fin, c'est la fin du commencement (vers la follie). :grin:

Je suis également vos échanges que je trouve très intéressants, mais pour le moment mes préoccupations sont bien plus basiques.

J’espère seulement être en mesure de suivre et contribuer à vos échanges un de ces jours (même lointain).

L’idée d’utiliser plusieurs processeurs pour diverses tâches, peut-être très intéressante, et peut apporter un niveau de sécurité supplémentaire, car un processeur peut de temps en temps surveiller l’autre et réagir en cas de dysfonctionnement.

Yop bribri,

Brisebee: J’espère seulement être en mesure de suivre et contribuer à vos échanges un de ces jours (même lointain).

Be tu contribues déjà pas mal, rien qu'avec ton doc très détaillés sur ton cahier des charges et schématisation que j'ai relus plusieurs fois (dans mon fauteuil au coin du feu avec un cigare et un vieux whisky XD) car je le trouve intéressant. Il y a des chose que je ne connais pas,schémas, etc. ;)

J’ai câblé au propre et testé la plus grande partie de la carte unité de gestion UC.
Elle comporte :

  • La carte Arduino Mega 2560
  • La carte Ethenet Shield W5100
  • La petite carte RTC-DS 1307
  • Un afficheur LCD 4x16 caractères
  • La connectique pour raccorder la carte d’interfaçage et les interfaces des unités de gestion (chauffage et arrosage)
  • Un watchdog (pas encore câblé au propre)

Tous les tests de fonctionnement du matériel sont OK.

J’ai rajouté un watchdog matériel qui se déclenche et remet à zéro la carte Arduino Mega 2560 au bout d’une seconde environ, s’il n’est pas lui-même remis à zéro par le programme.

Je ne sais pas si c’est bien utile, je n’ai pas encore regardé de près le watchdog interne du microcontrôleur (qui doit avoir la même fonction) mais je me suis dit que ce sera une sécurité supplémentaire (et comme j’ai de la place sur la carte et que cela met en œuvre des composants standards que j’avais en stock !)

Que pensez-vous de cette option ?

Je vous joins le schéma de ma carte unité de gestion UC.

J’ai baptisé mon système DOMOWEB 2012

J’attends vos critiques.

Unité de gestion carte UC.pdf (59.8 KB)

Yep!

First, tu es sur de ne pas avoir besoin de pwm, parce que là tu les a tous mangé XD L'afficheur peut être piloté avec un shift register ??? (tu ne gagnerais pas grand chose, c'est une question pour la forme)

Le 4060 est bienvenu, en effet le watchdog interne se contente de faire uniquement un reset software, il reprend au setup() si il ne reçoit pas le signal life à temps. Un watchdog hardware te permettra un reboot complet de la carte en cas de défaillance, c'est une bien meilleur option et tout le monde apportera son crédit à cette solution ;)

(En aparté, Il faut juste faire gaffe à certain péripherique qui ont une option reset propre, mon afficheur tactile par exemple freeze si je lance un reset de l'arduino, un second reset et tout est ok...il faut être prudent avec le timing de certain peripherique.)

EDIT 1 : J'envisage également un watchdog hardware à base de 555. Je ne connais pas trop le 4060, alors avantages/inconvénients, gestion arduino ???

@+

Zoroastre.

zoroastre:

zoroastre: tu es sur de ne pas avoir besoin de pwm, parce que là tu les a tous mangé

Non à priori je n'en ai pas besoin => j'en ai gardé une (la 9).

De toute manière j'ai fait mon câblage en wrapping, je pourrais donc modifier si je suis coincé.

Je vais avoir besoin de pas mal d'entrées sorties digitales, car j'ai décidé de reboucler les sorties (signaux directement prélévé sur les actionneurs et adaptés donc 230 VAC en 5 VDC et 24 VAC en 5 VDC) pour pouvoir contrôler l'état des actionneurs même en mode manuel.

zoroastre: Un watchdog hardware te permettra un reboot complet de la carte en cas de défaillance, c'est une bien meilleur option et tout le monde apportera son crédit à cette solution ;)

Cela conforte mon idée, je vais donc le câbler au propre.

Merci @+

Yep!

Je vais avoir besoin de pas mal d'entrées sorties digitales

Si tu as besoin de pas mal de sorties digitales, les registres à décalage sont interessants, le 74HC595 (le plus documenté) ou les TPIC595 (TPIC6B595, etc) sont des chip série vers parallèle/série. Uniquement 3 sorties arduino sont nécesaires pour piloter ces composants (8 sorties) par communication SPI, tu peux, qui plus est, chainer les chip les uns derrière les autres jusqu'à "je ne sais plus combien :grin: ".

http://www.arduino.cc/en/Tutorial/ShiftOut

Tu réduis ainsi ton nombre de sortie digital tout en gagnant en nombre d'entré ;)

Le 74HC595 tolère max 70mA, (1x25 + 7x35 mA) par sortie. Le TPIC6B596 tolère max 0.5A/50v, 150 mA par sortie (au nombre de 8). Une option interessante pour piloter de nombreux relais par exemple. Le TPIC6595 tolère max 1.5A/45v, 250 mA par sortie.

Pour réduire le nombre d'entrée, je n'ai pas de solution qui me vienne en tête à par les ADC, CD4021...dans ce cas là, il faut être à l'ecoute des données entrantes, ce peut être interessant dans certain type de montage/programme...

@+

Zoroastre.