comunicação múltipla arduino (1 mestre, n escravos)

8

Eu gostaria de desenvolver uma rede mestre / escravo que consiste em:

  • 1 Mestre do Arduino que lê sensores e gera perfis de velocidade de rampa com base nos sinais do sensor e depois envia essas rampas para escravos

  • 3 (ou mais) escravos do Arduino que controlam a velocidade dos servomotores de 12V seguindo as rampas enviadas pelo mestre

O que é um bom protocolo de comunicação para conseguir isso? Serial (SPI)? I2C? Algo mais? Se for serial, o novo Arduino Leonardo é uma boa escolha? Que questões devo considerar ao selecionar um protocolo?

Estou imaginando algo como:

Mestre:

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

Escravo 1:

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

E comunicação serial na qual o RX / TX do mestre é enviado a todos os escravos.

Parece uma solução razoável?

nkint
fonte
Você só quer enviar exatamente a mesma informação para todos os escravos? Os escravos precisam responder?
quer
não, eles não precisam responder!
Nkint 3/08
a que distância os escravos estarão?
geometrikal
eu acho que há mais de 15 metros
nkint

Respostas:

12

Pelo que entendi, você deseja enviar dados diferentes para cada um dos escravos, mas os escravos não precisam enviar dados de volta.

O I2C é um barramento endereçado; portanto, se você atribuir um endereço I2C diferente para cada um dos escravos, precisará de apenas dois fios para enviar os dados. Se necessário, você também pode solicitar os dados. Os AVRs do Arduino possuem um barramento serial compatível com I2C. E você pode estender para mais de 3 escravos sem hardware extra, até um máximo de 127.

Os UARTs não têm endereçamento, portanto, você precisaria de 3 UARTs (que o AVR não possui) ou adicionar lógica externa para alternar entre as linhas UART (que custa dinheiro). Cada escravo adicional significa um custo extra. Não recomendado.
editar
Como Chris diz, você pode usar o UART para criar um barramento multiponto. E então você terá que adicionar endereçamento, o que faz com que o seu UART funcione um pouco como o I2C, mas depois assíncrono e sem hardware de correspondência de endereços como o I2C. Portanto, ainda não é realmente uma vantagem. fim de edição

O SPI também usa linhas compartilhadas para dados: um único MOSI e as linhas MISO conectadas. Para abordar cada escravo individualmente, você precisará de uma linha SS (Slave Select) por escravo. Portanto, são pelo menos 5 E / S: MOSI, SCK, 3 SS e MISO se você também quiser ler dados dos escravos. Cada escravo adicional adiciona 1 pino de E / S ao mestre. ×

insira a descrição da imagem aqui

Eu acho que o I2C é a melhor solução, exigindo o menor número de fios. O protocolo é um pouco mais complexo que o UART ou SPI, mas como o AVR possui o hardware, deve ser fácil de usar.

stevenvh
fonte
2
A alegação de que vários UARTs ou lógica externa seriam necessários não é precisa. A comunicação UART com barramento é feita o tempo todo, usando o endereçamento de software. Com transmissão e recepção compartilhadas, isso não requer mais pinos do que o I2C.
Chris Stratton
@ Chris - Bom ponto, vou atualizar minha resposta.
stevenvh
1
@capcom - Adicionei um diagrama de blocos para o SPI. MOSI é produzido para o mestre e usado para os escravos. MISO é emitido para os escravos e entrada para o mestre. Sim, você baixa o SS do escravo para o qual deseja enviar dados. O SS não serve apenas para indicar o início e o fim da comunicação, mas também um escravo não selecionado deve tornar sua MISO alta impedância para conflitos de barramento.
stevenvh
2
@nkint - 8 m terão uma capacitância em torno de 800 pF, e o I2C permite apenas que 400 pF atinjam a velocidade de borda necessária. Você precisará usar um extensor de barramento como o P82B715 , que conduzirá o barramento em até 50 m de cabo.
Stevenvh 6/10/12
1
@stevenvh o P82B715 funciona muito bem e é realmente fácil de conectar!
Nkint 02/12/12
5

Estou assumindo que por série você quer dizer UART? Observe que UART, SPI, I2C são todos protocolos seriais.

SPI ou I2C seria bom para isso, pois ambos usam a arquitetura mestre / escravo.
Sem incluir terra, para 3 escravos, o SPI exigiria 6 pinos (MOSI, MISO, CLK + 3 pinos SS) e o I2C apenas dois (SDA e SCK)
provavelmente escolheria o I2C, supondo que você não precise de uma transferência de dados muito alta taxas (<400kHz)

Quanto mais escravos você adicionar, menor será o SPI, pois você precisará de outro SS (escravo) para cada novo escravo. Com o I2C, isso não é um problema, pois o endereçamento faz parte do protocolo, portanto, você ainda precisa apenas das 2 linhas (mais terra).

Para o Arduino, deve haver uma série de tutoriais com bibliotecas I2C / SPI e código de exemplo para os dois itens acima, o que deve tornar bastante indolor a instalação e a execução.

Oli Glaser
fonte
Você está certo, os dados são diferentes para cada escravo. Fui enganado pelo nome da função "send_to_all", mas parece usar uma rampa diferente para cada uma (elas são indexadas). Eu apaguei minha primeira resposta.
Stevenvh
1

Esquemas de sinalização assíncrona compartilhada semelhantes ao RS485 também devem ser possíveis.

Se você não estiver usando drivers / receptores de linha (apenas os pinos ATMEGA), é necessário fazer do UART TX uma entrada quando não for a sua vez de falar. Se você estiver usando drivers de linha, precisará usar um pino adicional para controlar a habilitação de tristate no driver de linha quando não for a sua vez de falar.

Lembre-se também de que você não pode simplesmente tristar o transmissor quando o último byte for aceito no registro de transmissão (o ponto em que você poderia enviar outro caractere); em vez disso, certifique-se de manter o transmissor ou o driver de linha ativado até que a palavra seja totalmente deslocado.

Nos esquemas em que você transmite e recebe no mesmo fio (ou par diferencial), leve em consideração que você ouvirá suas próprias transmissões.

Chris Stratton
fonte
1

No caso especial que você deseja conectar via UART , você pode usar o UART RS485 MODBUS . Este é um protocolo de comunicação com endereços de software, função, soma de verificação.

EU PENSO : É mais confiável que I²C ou SPI devido ao RS-485 e usa menos fios que o SPI.

NOTA: Ele pode ser implementado como padrão, com algumas bibliotecas, mas pode ser caro, pois você precisa de um módulo RS485 para cada escravo e um para o mestre, mas é compatível com uma rede existente. Mas você pode fazer isso com menos custo usando componentes herdados e criando seu próprio dispositivo. O MAX 485 pode ser o componente base para fazer um barramento Hardware 485 ou usando um software RS485

Alexis Paques
fonte
0

A solução mais simples para os requisitos específicos seria um transmissor RS-422 em uma linha TX no mestre (Controlador de barramento).

Todos os RTs ouvem as mensagens de transmissão, mas apenas autenticam e executam os comandos direcionados a ele através do endereço RT.

Se um protocolo de barramento semelhante a 1553 fosse usado, seria fácil de implementar.

Stu
fonte