Arduino Uno R3 + Ethernet Shield W5100 + Motor Shield L293D não funcionam juntos

Olá, estou tentando utilizar o Arduino Uno R3 + Ethernet Shield W5100 + Motor Shield L293D para comandar 2 motores de passo via Broker MQTT.

Quando uso apenas o L293D, consigo ativar os motores, quando uso apenas o W5100, consigo receber as mensagens do broker MQTT.

Porém, quando ativo as duas juntas, só consigo a comunicação de rede e os motores param de funcionar. Mais especificamente quando atribuo o endereço IP via a linha de comando Ethernet.begin(mac, ip, dns, gateway, subnet);

Parece que elas têm algum tipo de conflito. O mais interessante é que a ativação exclusiva de cada uma funciona mesmo com o conjunto todo montado e ligado.

Vocês têm algum exemplo que eu possa usar para ativas as duas Shields simultaneamente? Preciso enviar via MQTT o ângulo de giro para um determinado motor.

Obrigado.

Quando uso apenas o L293D, consigo ativar os motores

Post o código usado para testar o L293D.

quando uso apenas o W5100, consigo receber as mensagens do broker MQTT.

Post o código usado para testar o W5100.

Porém, quando ativo as duas juntas, só consigo a comunicação de rede e os motores param de funcionar

Post o código que é sua melhor tentativa de unir os L293D e W5100.

Olá pessoal, devido ao tamanho do código ser muito grande, estou anexando ele já no formato da IDE do Arduino.

Teste_02.ino (9.79 KB)

giova014:
Post o código usado para testar o W5100.

Segue abaixo o código:

/*
 Basic MQTT example

 This sketch demonstrates the basic capabilities of the library.
 It connects to an MQTT server then:
  - publishes "hello world" to the topic "outTopic"
  - subscribes to the topic "inTopic", printing out any messages
    it receives. NB - it assumes the received payloads are strings not binary

 It will reconnect to the server if the connection is lost using a blocking
 reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
 achieve the same result without blocking the main loop.
 
*/

#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };    //Define o MAC ADDRESS da placa de rede
byte ip[] = { 172, 30, 1, 26 };                         //Define o endereço IP
byte dns[] = { 172, 30, 1, 3 };                         //Define o servidor de DNS
byte gateway[] = { 172, 30, 1, 1 };                     //Define o gateway
byte subnet[] = { 255, 255, 255, 0 };                   //Define a máscara de rede

EthernetClient ethClient;
PubSubClient client(ethClient);

void callback(char* topic, byte* payload, unsigned int length) {
  String MSG;
  
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i=0;i<length;i++) {
    Serial.print((char)payload[i]);
    MSG = MSG + (char)payload[i];
  }
  Serial.println();
  Serial.println();
  Serial.print(MSG);
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoClient")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic","hello world");
      // ... and resubscribe
      client.subscribe("inTopic");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup()
{
  //Inicializa a porta serial de controle
  Serial.begin(9600);

  // You can use Ethernet.init(pin) to configure the CS pin
  Ethernet.init(10);                              // Most Arduino shields
  //Inicializa o Ethernet Shield
  Ethernet.begin(mac, ip, dns, gateway, subnet);

  client.setServer("172.30.1.25", 1883);      //Conecta no servidor Mosquitto
  client.setCallback(callback);

  // Allow the hardware to sort itself out
  delay(2000);
}

void loop()
{
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}

giova014:
Post o código usado para testar o L293D.

Segue abaixo o código:

//Programa : Motor de passo 5v 28BYJ-48 com Motor_2 Motor Shield L293D
#include <AFMotor.h>

double passos_total = 2048;   //Numero de passos para 1 rotacao total
//int porta_motor = 2;          //1 para motor em M1/M2 e 2 para motor em M3/M4
int angulo = 9;              //Angulo de rotacao do eixo
int angulo2 = 9;
double numero_de_passos = 0;  //Armazena o numero de passos que o motor vai girar
double numero_de_passos2 = 0;

AF_Stepper Motor_1(passos_total, 1);  //Define os parametros do motor
AF_Stepper Motor_2(passos_total, 2);  //Define os parametros do motor

void setup()
{
  Motor_1.setSpeed(5); //Define a velocidade de rotacao
  Motor_2.setSpeed(5); //Define a velocidade de rotacao
  Serial.begin(9600);
}
 
void loop()
{
  //Calcula a quantidade de passos, baseado no angulo determinado
  numero_de_passos = angulo / (360 / passos_total);
  numero_de_passos2 = angulo2 / (360 / passos_total);
   
  //Mostra no serial monitor o numero de passos calculados
  Serial.print("Forward: ");
  Serial.println(numero_de_passos);
  Serial.print("Backward: ");
  Serial.println(numero_de_passos2);
   
  //Move o motor. Use FORWARD para sentido horario,
  //BACKWARD para anti-horario
  Motor_1.step(numero_de_passos, FORWARD, SINGLE);
  Motor_1.release();
  Motor_2.step(numero_de_passos, BACKWARD, SINGLE);
  Motor_2.release();
  delay(1000);
}

mgrafulha:
Olá pessoal, devido ao tamanho do código ser muito grande, estou anexando ele já no formato da IDE do Arduino.

Remova o delay(1000) de seu loop, vai ficar assim:

void loop()
{
  if (!client.connected())
  {
    reconnect();
  }
  client.loop();
}

Teste novamente.

Olá Giova, infelizmente não surtiu efeito. Em anexo as telas da correção e do monitor serial.

Quando eu envio a mensagem "2B50" para o tópico "GRB0001/OP" do server Mosquitto (servidor local que estou usando para testes), o Arduino deveria fazer o motor número 2 girar 1/4 de volta no sentido anti-horário.

O código até identifica o comando (vide captura da tela do monitor serial), mas não gira.

Se tiver outra ideia, será bem-vinda.

O shield W5100 se comunica com o Arduino Uno através de SPI.
De acordo com a documentação Arduino - SPI, os pinos usados são:
MOSI -> 11
MISO -> 12
SCK -> 13
SS -> 10

O shield L293D se comunica com o Arduino através de pinos digitais.
De acordo com seu código, você está usando a biblioteca AFMotor.
De acordo com o código da biblioteca AFMotor.h, os pinos usados são:
MOTORLATCH -> 12
MOTORCLK -> 4
MOTORENABLE -> 7
MOTORDATA -> 8

Portanto, os shields estão com conflito na utilização do pino 12.

Duas soluções possíveis:

  1. Troque o Arduino Uno por um Mega, pois os pinos SPI do Mega não dão conflito
  2. Mantendo o Uno, não é possível mudar os pinos da interface SPI, então deve mudar fisicamente (fios externos) o pino 12 do shield do L293D para outro pino (por exemplo 9, NÃO mude para o 13, pois tem o LED_BUILTIN).

Caso seguir a solução 2, é necessário alterar o arquivo da biblioteca no caminho:
"Documentos\Arduino\libraries\Adafruit-Motor-Shield-library\AFMotor.h"
Mudando a linha 138:

#define MOTORLATCH 12

para o novo pino (exemplo 9):

#define MOTORLATCH 9

Deixe o loop sem o delay(1000), conforme sugestão anterior, e teste novamente.

Obrigado Giova, assim que possível vou testar e escrevo um Post com o resultado. Só vai demorar um pouquinho porque vou precisar comprar um extensor dos pinos, assim não altero em definitivo o Shield.

Obrigado pela dica.