communication arduino multiple (1 maître, n esclaves)

8

Je souhaite développer un réseau maître / esclave composé de:

  • 1 maître Arduino qui lit les capteurs et génère des profils de rampe de vitesse en fonction des signaux des capteurs, puis envoie ces rampes aux esclaves

  • 3 (ou plus) esclaves Arduino qui contrôlent la vitesse des servomoteurs 12V suivant les rampes envoyées par le maître

Qu'est-ce qu'un bon protocole de communication pour y parvenir? Série (SPI)? I2C? Autre chose? S'il est en série, le nouvel Arduino Leonardo est-il un bon choix? Quels problèmes dois-je considérer lors de la sélection d'un protocole?

J'imagine quelque chose comme:

Maître:

void loop() {
    update_ramps()
    for(int i=0; i< num_slaves; i++) {
        send_to_all(i, ramps[i]);
    }
}

Esclave 1:

const int id = 1;
int recived_id, recived_value;
void loop() {
    read_data();
    if(recived_id == id) { 
        do_motor_step(recived_value);
    }
}

Et communication série dans laquelle RX / TX du maître est envoyé à tous les esclaves.

Cela semble-t-il une solution raisonnable?

nkint
la source
Vous voulez juste envoyer exactement les mêmes informations à tous les esclaves? Les esclaves doivent-ils répondre du tout?
Oli Glaser
non, ils n'ont pas besoin de répondre!
nkint
à quelle distance seront les esclaves?
geometrikal
je ne pense pas plus de 15 mètres
nkint

Réponses:

12

Si je comprends bien, vous voulez envoyer des données différentes à chacun des esclaves, mais les esclaves n'ont pas à renvoyer de données.

I2C est un bus adressé, donc si vous attribuez une adresse I2C différente à chacun des esclaves, vous n'aurez besoin que de deux fils pour envoyer les données. Si nécessaire, vous pouvez également demander des données. Les AVR de l'Arduino ont un bus série compatible I2C. Et vous pouvez étendre à plus de 3 esclaves sans matériel supplémentaire, jusqu'à un maximum de 127.

Les UART n'ont pas d'adressage, vous auriez donc besoin de 3 UART (que l'AVR n'a pas) ou d'ajouter une logique externe pour basculer entre les lignes UART (ce qui coûte de l'argent). Chaque esclave supplémentaire signifie un coût supplémentaire. Non recommandé.
edit
Comme Chris le dit, vous pouvez utiliser UART pour créer un bus multipoint. Et ensuite, vous devrez ajouter l'adressage, ce qui fait que votre UART fonctionne un peu comme I2C, mais ensuite asynchrone, et sans matériel de correspondance d'adresse comme l'I2C. Donc toujours pas vraiment un avantage. fin du montage

SPI utilise également des lignes partagées pour les données: une seule MOSI et les lignes MISO connectées. Pour adresser chaque esclave individuellement, vous aurez besoin d'une ligne SS (Slave Select) par esclave. C'est donc au moins 5 E / S: MOSI, SCK, 3×SS et MISO si vous souhaitez également lire les données des esclaves. Chaque esclave supplémentaire ajoute 1 broche d'E / S sur le maître.

entrez la description de l'image ici

Je pense que l'I2C est la meilleure solution, nécessitant le moins de fils. Le protocole est un peu plus complexe que UART ou SPI, mais comme l'AVR a le matériel pour cela, il devrait être facile à utiliser.

Stevenvh
la source
2
L'affirmation selon laquelle plusieurs UART ou une logique externe seraient nécessaires n'est pas exacte. La communication UART par bus se fait tout le temps, en utilisant l'adressage logiciel. Avec la transmission et la réception partagées, cela ne nécessite pas plus de broches que l'I2C.
Chris Stratton
@Chris - Bon point, je mettrai à jour ma réponse.
stevenvh
1
@capcom - J'ai ajouté un schéma fonctionnel pour le SPI. MOSI est sortie pour le maître et entrée pour les esclaves. MISO est sortie pour les esclaves et entrée pour le maître. Oui, vous réduisez le SS pour l'esclave auquel vous souhaitez envoyer des données. Le SS sert non seulement à indiquer le début et la fin de la communication, mais également un esclave non sélectionné doit rendre son MISO à haute impédance pour les conflits de bus.
stevenvh
2
@nkint - 8 m auront une capacité d'environ 800 pF, et I2C ne permet qu'à 400 pF d'obtenir la vitesse de bord requise. Vous devrez utiliser un prolongateur de bus comme le P82B715 , qui conduira le bus sur jusqu'à 50 m de câble.
stevenvh
1
@stevenvh le P82B715 fonctionne très bien et il est vraiment facile à brancher!
nkint
5

Je suppose que par série vous voulez dire UART? Notez que UART, SPI, I2C sont tous des protocoles série.

SPI ou I2C conviendrait pour cela car ils utilisent tous les deux l'architecture maître / esclave.
Sans la terre, pour 3 esclaves, SPI nécessiterait 6 broches (MOSI, MISO, CLK + 3 broches SS) et I2C seulement deux (SDA et SCK)
Je choisirais probablement I2C, en supposant que vous n'avez pas besoin d'un transfert de données très élevé taux (<400 kHz)

Plus vous ajoutez d'esclaves, moins le SPI est pratique, car vous avez besoin d'un autre SS (Slave Select) pour chaque nouvel esclave. Avec I2C, ce n'est pas un problème car l'adressage fait partie du protocole, vous n'avez donc besoin que des 2 lignes (plus la masse).

Pour Arduino, il devrait y avoir toute une série de tutoriels avec les bibliothèques I2C / SPI et un exemple de code pour les deux ci-dessus, ce qui devrait le rendre assez facile à mettre en service.

Oli Glaser
la source
Vous avez raison, les données sont différentes pour chaque esclave. J'ai été induit en erreur par le nom de la fonction "send_to_all", mais elle semble utiliser une rampe différente pour chacune (elles sont indexées). J'ai supprimé ma première réponse.
stevenvh
1

Des schémas de signalisation asynchrones partagés similaires à RS485 devraient également être possibles.

Si vous n'utilisez pas de pilotes / récepteurs de ligne (juste les broches ATMEGA nues), vous devez faire de l'UART TX une entrée lorsque ce n'est pas votre tour de parler. Si vous utilisez des pilotes de ligne, vous devez utiliser une broche supplémentaire pour contrôler l'activation de l'état sur le pilote de ligne lorsque ce n'est pas votre tour de parler.

Sachez également que vous ne pouvez pas simplement émettre l'émetteur lorsque le dernier octet est accepté dans le registre de transmission (le point où vous pouvez envoyer un autre caractère), à ​​la place, vous devez vous assurer de garder l'émetteur ou le pilote de ligne activé jusqu'à ce que le mot ait été complètement déplacé.

Dans les schémas où vous transmettez et recevez sur le même fil (ou paire différentielle), tenez compte du fait que vous entendrez vos propres transmissions.

Chris Stratton
la source
1

Dans le cas particulier où vous souhaitez vous connecter via UART , vous pouvez utiliser le UART RS485 MODBUS . Il s'agit d'un protocole de communication avec adresses logicielles, fonction, somme de contrôle.

JE PENSE : Il est plus fiable que I²C ou SPI en raison de RS-485 et utilise moins de fils que SPI.

REMARQUE: Il peut être implémenté en standard, avec certaines bibliothèques mais il peut être coûteux car vous avez besoin d'un module RS485 pour chaque esclave et un pour le maître, MAIS il est compatible avec un réseau existant. Mais vous pouvez le faire moins cher en utilisant des composants hérités et en créant votre propre appareil. Le MAX 485 pourrait être le composant de base pour créer un bus Hardware 485 ou en utilisant un logiciel RS485

Alexis Paques
la source
0

La solution la plus simple aux exigences spécifiques serait un émetteur RS-422 sur une ligne TX sur le maître (contrôleur de bus). Il serait déployé vers les multiples récepteurs (terminaux distants).

Tous les RT entendraient les messages diffusés mais n'authentifieraient et n'exécuteraient que les commandes qui lui étaient adressées via l'adresse RT.

Si un protocole de bus similaire à 1553 était utilisé, il serait facile à mettre en œuvre.

Stu
la source