Comunicacion WIFI con WEMOS

Buenos días

Estoy haciendo un proyecto para calcular un peso determinado con arduino. El proyecto basicamente consiste en verificar que el usuario ha puesto un peso especifico y activar un electroiman que abrirá un cajón.

Lo estoy haciendo con una WEMOS D1R2 (WEMOS A) ya que mi cliente desea que vaya por wifi. Estoy haciendo uso de Node-Red y MQTT.

Mi cliente quiere que además de poder activar el electroiman a través de la consola de Node-red, tener un control manual, por botón (un switch on-off), para poder activarlo si el usuario no consigue poner el peso indicado por lo que entiendo que tendré que usar otra WEMOS B

La duda que tengo es:
¿Necesito configurar una tarjeta como servidor y otro como cliente?. Ahora mismo, el WEMOS A lo tengo definido como cliente.
¿Puedo publicar mensajes desde el WEMOS B para que se active el electroiman en el WEMOS A?

Os añado mi esquema, código y Node-Red por si me podeis ayudar.

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <HX711.h>

const int DOUT=16;        //GPIO16 - D0
const int CLK=5;          //GPIO05 - D1
const byte lockPin=4;    // GPIO04 - D2 A este pin se le enviará un pulso ALTO cuando se ingrese la solución correcta para abrir cajón

// Modifica estos valores para tu red.
const char* ssid = "***********";
const char* password = "*********";
//const char* ssid = "***********";
//const char* password = "*************";
const char* mqtt_server = "broker.mqtt-dashboard.com";

WiFiClient espClient;
PubSubClient client(espClient);
int value = 0;

// Timers auxiliar variables
long now = millis();
long lastMeasure = 0;

HX711 balanza;

void(* Resetea) (void) = 0;

void setup_wifi() {
  delay(10);
  // Arrancamos la conexión via WIFI a la red
  Serial.println();
  Serial.print("Conectando a... ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi conectada");
  Serial.print("Dirección IP: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Llega mensaje [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    char receivedChar = (char)payload[i];
    Serial.print(receivedChar);
    ctrlMensajes(topic, receivedChar);
  }
  Serial.println();
}

void ctrlMensajes(String topic, byte receivedChar){
  if (topic == "peso/desbloquear"){ 
    if(receivedChar == '1'){
      Serial.println("Control wifi resuelve");
      desbloquea();
    } else {
      Serial.println("Control wifi NO resuelve");
      digitalWrite(lockPin, LOW);
      delay(50);
      digitalWrite(lockPin, HIGH);
    }
  }
  if (topic == "peso/reset"){
    if(receivedChar == '1'){
      Serial.println("Control wifi resetea");
      Resetea();
    }
  }
  if (topic == "peso/boton/desbloquear"){ 
    if(receivedChar == '0'){
      Serial.println("Control botón resuelve");
      desbloquea();
    } else {
      Serial.println("Control botón NO resuelve");
      digitalWrite(lockPin, LOW);
      delay(50);
      digitalWrite(lockPin, HIGH);
    }
  }
  if (topic == "peso/boton/reset"){ 
    if(receivedChar == '0'){
      Serial.println("Control botón resetea");
      Resetea();
    }
  }
}

void reconnect() {
  // Bucle hasta reconectar
  while (!client.connected()) {
    Serial.print("Esperando conexión MQTT...");
    // Crea un client ID aleatorio
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Esperando conectar
    if (client.connect(clientId.c_str())) {
      Serial.println("conectado");
      // Una vez conectado, publica...
      // ... y subscribe
      client.subscribe("peso/desbloquear");
      //client.subscribe("peso/control");
      client.subscribe("peso/reset");
    } else {
      Serial.print("fallo, rc=");
      Serial.print(client.state());
      Serial.println(" intentalo de nuevo en 5 segundos");
      delay(5000);
    }
  }
}



void setup() {
  Serial.begin(115200);
  balanza.begin(DOUT, CLK);
  pinMode(lockPin, OUTPUT);          // Pone el lockPin como salida
  digitalWrite(lockPin, HIGH);

  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

  Serial.print("Lectura del valor del ADC:  ");
  Serial.println(balanza.read());
  Serial.println("No ponga ningun  objeto sobre la balanza");
  Serial.println("Destarando...");
  Serial.println("...");
  
  balanza.set_scale(401842.69); // Establecemos la escala
  balanza.tare(20);  //El peso actual es considerado Tara.
  
  Serial.println("Listo para pesar");  
  
}

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

  now = millis();
  // Publica nuevo peso cada medio segundos
  if (now - lastMeasure > 500) {
     lastMeasure = now;
    Serial.print("Peso: ");
    Serial.print(balanza.get_units(20),3);
    Serial.println(" gr");
    // Publica el valor del peso al topic "peso/gramos"

    char pesoLeido[7];
    dtostrf(balanza.get_units(20), 1, 3, pesoLeido);

    client.publish("peso/gramos", pesoLeido);
  }
}

void desbloquea() {
  digitalWrite(lockPin, HIGH);
  delay(50);
  digitalWrite(lockPin, LOW);
}

[
    {
        "id": "51f63d20.78e724",
        "type": "tab",
        "label": "Prop Control ABADIA",
        "disabled": false,
        "info": ""
    },
    {
        "id": "2b28b35b.5ac42c",
        "type": "mqtt in",
        "z": "51f63d20.78e724",
        "name": "peso/gramos",
        "topic": "peso/gramos",
        "qos": "2",
        "datatype": "auto",
        "broker": "678a13cd.298acc",
        "x": 150,
        "y": 460,
        "wires": [
            [
                "1ceeeb19.704b85"
            ]
        ]
    },
    {
        "id": "a69f0c94.0b13b",
        "type": "ui_button",
        "z": "51f63d20.78e724",
        "name": "",
        "group": "1a2f4016.8732a",
        "order": 1,
        "width": 2,
        "height": 1,
        "passthru": false,
        "label": "Comenzar",
        "tooltip": "",
        "color": "",
        "bgcolor": "green",
        "icon": "",
        "payload": "{\"payload\":\"on\",\"timeout\":600,\"warning\":30}",
        "payloadType": "json",
        "topic": "",
        "x": 150,
        "y": 680,
        "wires": [
            [
                "ffbf4444.f7fcc8"
            ]
        ]
    },
    {
        "id": "8aba63f3.1051b",
        "type": "ui_button",
        "z": "51f63d20.78e724",
        "name": "",
        "group": "1a2f4016.8732a",
        "order": 2,
        "width": 2,
        "height": 1,
        "passthru": false,
        "label": "Parar",
        "tooltip": "",
        "color": "",
        "bgcolor": "red",
        "icon": "",
        "payload": "{     \"payload\": \"cancel\" }",
        "payloadType": "json",
        "topic": "",
        "x": 130,
        "y": 719,
        "wires": [
            [
                "6fb4b3c7.fd909c"
            ]
        ]
    },
    {
        "id": "28353e08.f85972",
        "type": "ui_button",
        "z": "51f63d20.78e724",
        "name": "",
        "group": "1a2f4016.8732a",
        "order": 3,
        "width": 2,
        "height": 1,
        "passthru": false,
        "label": "Reset",
        "tooltip": "",
        "color": "",
        "bgcolor": "orange",
        "icon": "",
        "payload": "{\"timeout\": 600 }",
        "payloadType": "json",
        "topic": "",
        "x": 130,
        "y": 780,
        "wires": [
            [
                "fce9982a.c1f0d8"
            ]
        ]
    },
    {
        "id": "5470c7ee.ab25e8",
        "type": "inject",
        "z": "51f63d20.78e724",
        "name": "Tick",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "1",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 138,
        "y": 835,
        "wires": [
            [
                "8602322c.8d193"
            ]
        ]
    },
    {
        "id": "ae79e7a4.c9c6f8",
        "type": "change",
        "z": "51f63d20.78e724",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "gameState",
                "pt": "global",
                "to": "playing",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 540,
        "y": 680,
        "wires": [
            [
                "c4878c1.1239f7"
            ]
        ]
    },
    {
        "id": "73bd1313.f4dfcc",
        "type": "change",
        "z": "51f63d20.78e724",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "gameState",
                "pt": "global",
                "to": "stopped",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "timeRemaining",
                "pt": "msg",
                "to": "timeRemaining",
                "tot": "global"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 520,
        "y": 720,
        "wires": [
            [
                "c4878c1.1239f7"
            ]
        ]
    },
    {
        "id": "ffbf4444.f7fcc8",
        "type": "switch",
        "z": "51f63d20.78e724",
        "name": "",
        "property": "gameState",
        "propertyType": "global",
        "rules": [
            {
                "t": "neq",
                "v": "playing",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 310,
        "y": 680,
        "wires": [
            [
                "ae79e7a4.c9c6f8"
            ]
        ]
    },
    {
        "id": "6fb4b3c7.fd909c",
        "type": "switch",
        "z": "51f63d20.78e724",
        "name": "",
        "property": "gameState",
        "propertyType": "global",
        "rules": [
            {
                "t": "neq",
                "v": "stopped",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 310,
        "y": 720,
        "wires": [
            [
                "73bd1313.f4dfcc"
            ]
        ]
    },
    {
        "id": "8602322c.8d193",
        "type": "function",
        "z": "51f63d20.78e724",
        "name": "Update Game Timer",
        "func": "// The current timestamp is injected at the start of the flow\nvar currentTime = msg.payload;\nvar lastTickTime = global.get(\"lastTickTime\")||currentTime;\nvar timeRemaining = global.get(\"timeRemaining\")||0;\nvar gameState = global.get(\"gameState\");\n\nif(gameState == \"playing\") {\n    // Reduce the time remaining based on the amount of time\n    // that has elapsed since the last tick count\n    timeRemaining -= (currentTime - lastTickTime);\n    \n    // Update the global variable\n    global.set(\"timeRemaining\", timeRemaining);\n\n    if(timeRemaining < 60000) {\n        msg.timeColour = \"red\";\n    }\n    else {\n        msg.timeColour = \"limegreen\";\n    }\n}\nelse {\n    msg.timeColour = \"white\";\n}\n\n\n    // Update the msg to carry formatted string        \n    msg.timeRemaining = timeRemaining;\n    \n    global.set(\"lastTickTime\", currentTime);\n    node.status({fill:\"green\",shape:\"dot\",text:timeRemaining});\n    // Only need to update UI is timeRemaining has changed\n    return msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 320.5,
        "y": 835,
        "wires": [
            [
                "c4878c1.1239f7"
            ]
        ]
    },
    {
        "id": "fce9982a.c1f0d8",
        "type": "change",
        "z": "51f63d20.78e724",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "timeRemaining",
                "pt": "global",
                "to": "3599999",
                "tot": "num"
            },
            {
                "t": "set",
                "p": "timeRemaining",
                "pt": "msg",
                "to": "3599999",
                "tot": "num"
            },
            {
                "t": "set",
                "p": "gameState",
                "pt": "global",
                "to": "stopped",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 320,
        "y": 780,
        "wires": [
            [
                "c4878c1.1239f7"
            ]
        ]
    },
    {
        "id": "90ae97d4.f95298",
        "type": "ui_template",
        "z": "51f63d20.78e724",
        "group": "1a2f4016.8732a",
        "name": "",
        "order": 4,
        "width": 0,
        "height": 0,
        "format": "<div layout=\"row\" layout-align=\"space-between\">   <!-- Possible layout-aligns include \"start center\" -->\n    <span class=\"label\">\n        Tiempo restante\n    </span> \n    <span class=\"value\" style=\"color:{{msg.timeColour}}; font-size:xx-large;\">\n        {{msg.formattedTimeRemaining}}\n    </span>\n</div>",
        "storeOutMessages": true,
        "fwdInMessages": true,
        "resendOnRefresh": false,
        "templateScope": "local",
        "x": 780,
        "y": 780,
        "wires": [
            []
        ]
    },
    {
        "id": "c4878c1.1239f7",
        "type": "function",
        "z": "51f63d20.78e724",
        "name": "Format Time",
        "func": "// Message from preceeding node is in milliseconds\nvar t = msg.timeRemaining / 1000;\nvar h = Math.floor(t / 3600);\nvar m = Math.floor(t % 3600 / 60);\nvar s = Math.floor(t % 3600 % 60);\n\n// Format into hh:mm:ss\nmsg.formattedTimeRemaining = (\"0\" + h).slice(-2) + \":\" + (\"0\" + m).slice(-2) + \":\" + (\"0\" + s).slice(-2);\n\n\nnode.status({fill:\"green\", shape:\"dot\", text:msg.formattedTimeRemaining});\n    \nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 550,
        "y": 780,
        "wires": [
            [
                "90ae97d4.f95298"
            ]
        ]
    },
    {
        "id": "e8ec36e8.2c42d8",
        "type": "comment",
        "z": "51f63d20.78e724",
        "name": "GAME COUNTER",
        "info": "",
        "x": 150,
        "y": 640,
        "wires": []
    },
    {
        "id": "40b5a290.0ec24c",
        "type": "ui_switch",
        "z": "51f63d20.78e724",
        "name": "",
        "label": "Reset",
        "tooltip": "",
        "group": "b2133989.aed9f8",
        "order": 3,
        "width": 0,
        "height": 0,
        "passthru": false,
        "decouple": "false",
        "topic": "peso/reset",
        "style": "",
        "onvalue": "1",
        "onvalueType": "num",
        "onicon": "fa-toggle-on",
        "oncolor": "",
        "offvalue": "0",
        "offvalueType": "num",
        "officon": "fa-toggle-off",
        "offcolor": "",
        "x": 130,
        "y": 520,
        "wires": [
            [
                "43baacab.f02624"
            ]
        ]
    },
    {
        "id": "43baacab.f02624",
        "type": "mqtt out",
        "z": "51f63d20.78e724",
        "name": "",
        "topic": "peso/reset",
        "qos": "",
        "retain": "",
        "broker": "678a13cd.298acc",
        "x": 390,
        "y": 520,
        "wires": []
    },
    {
        "id": "b977fd75.386d8",
        "type": "ui_switch",
        "z": "51f63d20.78e724",
        "name": "",
        "label": "Desbloquear",
        "tooltip": "",
        "group": "b2133989.aed9f8",
        "order": 2,
        "width": 0,
        "height": 0,
        "passthru": true,
        "decouple": "false",
        "topic": "peso/desbloquear",
        "style": "",
        "onvalue": "1",
        "onvalueType": "num",
        "onicon": "fa-toggle-on",
        "oncolor": "",
        "offvalue": "0",
        "offvalueType": "num",
        "officon": "fa-toggle-off",
        "offcolor": "",
        "x": 150,
        "y": 560,
        "wires": [
            [
                "d3153453.dd1c48"
            ]
        ]
    },
    {
        "id": "d3153453.dd1c48",
        "type": "mqtt out",
        "z": "51f63d20.78e724",
        "name": "",
        "topic": "peso/desbloquear",
        "qos": "",
        "retain": "",
        "broker": "678a13cd.298acc",
        "x": 410,
        "y": 560,
        "wires": []
    },
    {
        "id": "60db7816.122ce8",
        "type": "comment",
        "z": "51f63d20.78e724",
        "name": "PESAR ALMAS",
        "info": "",
        "x": 120,
        "y": 420,
        "wires": []
    },
    {
        "id": "1ceeeb19.704b85",
        "type": "ui_gauge",
        "z": "51f63d20.78e724",
        "name": "Numero almas",
        "group": "b2133989.aed9f8",
        "order": 1,
        "width": 0,
        "height": 0,
        "gtype": "compass",
        "title": "",
        "label": "gr",
        "format": "{{value}}",
        "min": 0,
        "max": "1000",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "x": 400,
        "y": 460,
        "wires": []
    },
    {
        "id": "9cc1acd3.ecf69",
        "type": "ui_switch",
        "z": "51f63d20.78e724",
        "name": "",
        "label": "Reset",
        "tooltip": "",
        "group": "13297f90.c9646",
        "order": 3,
        "width": 0,
        "height": 0,
        "passthru": true,
        "decouple": "false",
        "topic": "ledStatus/red",
        "style": "",
        "onvalue": "1",
        "onvalueType": "num",
        "onicon": "fa-toggle-on",
        "oncolor": "",
        "offvalue": "0",
        "offvalueType": "num",
        "officon": "fa-toggle-off",
        "offcolor": "",
        "x": 150,
        "y": 980,
        "wires": [
            [
                "fb9df25b.e5e51"
            ]
        ]
    },
    {
        "id": "fb9df25b.e5e51",
        "type": "mqtt out",
        "z": "51f63d20.78e724",
        "name": "",
        "topic": "abadia/demonios/reset",
        "qos": "",
        "retain": "",
        "broker": "678a13cd.298acc",
        "x": 440,
        "y": 980,
        "wires": []
    },
    {
        "id": "ab308dc.d41877",
        "type": "ui_switch",
        "z": "51f63d20.78e724",
        "name": "",
        "label": "Desbloquear",
        "tooltip": "",
        "group": "13297f90.c9646",
        "order": 2,
        "width": 0,
        "height": 0,
        "passthru": true,
        "decouple": "false",
        "topic": "ledStatus/yellow",
        "style": "",
        "onvalue": "1",
        "onvalueType": "num",
        "onicon": "fa-toggle-on",
        "oncolor": "",
        "offvalue": "0",
        "offvalueType": "num",
        "officon": "fa-toggle-off",
        "offcolor": "",
        "x": 170,
        "y": 1020,
        "wires": [
            [
                "efdf423d.f3a11"
            ]
        ]
    },
    {
        "id": "efdf423d.f3a11",
        "type": "mqtt out",
        "z": "51f63d20.78e724",
        "name": "",
        "topic": "abadia/demonios/desbloquear",
        "qos": "",
        "retain": "",
        "broker": "678a13cd.298acc",
        "x": 470,
        "y": 1020,
        "wires": []
    },
    {
        "id": "7c27af33.1b07",
        "type": "comment",
        "z": "51f63d20.78e724",
        "name": "ALUMBRAR DEMONIOS",
        "info": "",
        "x": 170,
        "y": 920,
        "wires": []
    },
    {
        "id": "678a13cd.298acc",
        "type": "mqtt-broker",
        "name": "",
        "broker": "broker.mqtt-dashboard.com",
        "port": "1883",
        "clientid": "",
        "usetls": false,
        "compatmode": true,
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthRetain": "false",
        "birthPayload": "",
        "closeTopic": "",
        "closePayload": "",
        "willTopic": "",
        "willQos": "0",
        "willRetain": "false",
        "willPayload": ""
    },
    {
        "id": "1a2f4016.8732a",
        "type": "ui_group",
        "name": "CONTADOR",
        "tab": "5039d03.0a76f3",
        "order": 1,
        "disp": true,
        "width": "6",
        "collapse": false
    },
    {
        "id": "b2133989.aed9f8",
        "type": "ui_group",
        "name": "PESAR ALMAS",
        "tab": "5039d03.0a76f3",
        "order": 2,
        "disp": true,
        "width": "6",
        "collapse": false
    },
    {
        "id": "13297f90.c9646",
        "type": "ui_group",
        "name": "ALUMBRAR DEMONIOS",
        "tab": "5039d03.0a76f3",
        "order": 3,
        "disp": true,
        "width": "6",
        "collapse": false
    },
    {
        "id": "5039d03.0a76f3",
        "type": "ui_tab",
        "name": "EL MISTERIO DE LA SAGRA v2.0",
        "icon": "dashboard",
        "disabled": false,
        "hidden": false
    }
]

Tu Wemos debe ser cliente MQTT es quien va a publicar los mensajes. Deja al Raspi (supongo) con NodeRed y Mosquitto hacer su tarea.

Nota: no publiques claves personales. Te las editaré para evitar problemas.

Si claro, pero porque no dejas que lo haga Node-RED ya que lo tienes
tu envia el dato a Node-Red y Node-Red que publique la orden al Wemos B
Deja que me acomode con el foro y miro bien tus còdigos y te respondo con mas profundidad.

Gracias surbyte

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.