I have the following setup:
NodeMCU Ver. 2: Running Wifi Soft AP and MQTT Broker, programmed with Arduino.
Wemos D1 R2: Connected with a motor and running Arduino code as detailed below.
PC with win 7: B4J app.
The Wemos connects to the Node via Wifi, as does the PC. I can see the connection and the IP.
The B4J app, on pressing a button should send a single letter "f", "s" or "b" accordingly. I cannot get the payload on the Wemos to convert back to the letter sent.
I have tried using a tablet with a simple MQTT app to send the letters and it works fine. I think I have done something wrong in the B4J code but I am not sure what.
Thanks for any help.
Output from Wemos serial monitor after pressing "forwards" button - letter "f":
The Wemos code:
and lastly the B4J code:
NodeMCU Ver. 2: Running Wifi Soft AP and MQTT Broker, programmed with Arduino.
Wemos D1 R2: Connected with a motor and running Arduino code as detailed below.
PC with win 7: B4J app.
The Wemos connects to the Node via Wifi, as does the PC. I can see the connection and the IP.
The B4J app, on pressing a button should send a single letter "f", "s" or "b" accordingly. I cannot get the payload on the Wemos to convert back to the letter sent.
I have tried using a tablet with a simple MQTT app to send the letters and it works fine. I think I have done something wrong in the B4J code but I am not sure what.
Thanks for any help.
Output from Wemos serial monitor after pressing "forwards" button - letter "f":
The Wemos code:
B4X:
/*
Wemos d1 r2
Connect to Wifi AP and to MQTT broker
Subscribe to topic "Motor1"
Start/Stop motor based on "f", "r" and "s"
Status: Working
*/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
const char* ssid = "Rover AP";
const char* password = "";
const char* mqtt_server = "192.168.4.1";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
const char* outTopic = "Motor1"; // MQTT Topic for control
// Setup motor
#define IN1 D1
#define IN2 D2
#define IN3 D6
#define IN4 D7
int Steps = 0;
boolean Direction = true; // cw
boolean MotorStatus = false; // motor is off
// Setup Wifi connection
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA); // we need this or we cannot connect!
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
// Called when a message is received
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("]; ");
payload[length] = '\0';
String value = String((char*)payload);
// for (int i = 0; i < length; i++) {
// Serial.print((char)payload[i]);
// }
Serial.println(value);
Serial.println();
if(value.startsWith("s")){ResetMotor(); MotorStatus=false;}
if(value.startsWith("f")){ResetMotor(); MotorStatus=true;}
if(value.startsWith("r")){ResetMotor(); Direction=not(Direction); MotorStatus=true;}
Serial.print("Motor status: ");
Serial.println(MotorStatus);
}
// Reset motor
void ResetMotor() {
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
}
// Connect to MQTT Broker
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP8266Client")) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish(outTopic, "Motor Wemos booted");
// ... and resubscribe
client.subscribe(outTopic);
} 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() {
Serial.begin(115200);
setup_wifi(); // Connect to wifi
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
ResetMotor();
}
void loop() {
if (!client.connected()) {
reconnect();
}
if (MotorStatus){
stepper(1);
delay(25); // This delay is required for the motor to respond!!
}
client.loop();
}
void stepper(int xw){
for (int x=0;x<xw;x++){
switch(Steps){
case 0:
digitalWrite(IN1, HIGH);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
break;
case 1:
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
break;
case 2:
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, HIGH);
break;
case 3:
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
break;
default:
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
break;
}
SetDirection();
}
}
void SetDirection(){
if(Direction==1){ Steps++;}
if(Direction==0){ Steps--; }
if(Steps>3){Steps=0;}
if(Steps<0){Steps=3; }
}
and lastly the B4J code:
B4X:
#Region Project Attributes
#MainFormWidth: 600
#MainFormHeight: 600
#End Region
Sub Process_Globals
Private fx As JFX
Private MainForm As Form
Private btnBackwards As Button
Private btnConnect As Button
Private btnForward As Button
Private btnStop As Button
Private lbl1 As Label
Private lblConnectionText As Label
Private mqtt As MqttClient
Private serializator As B4XSerializator
Private user As String = ""
Private password As String = ""
Private outTopic As String="Motor1"
Private const port As Int = 1883
Private const Host As String="192.168.4.1"
End Sub
Sub AppStart (Form1 As Form, Args() As String)
MainForm = Form1
MainForm.SetFormStyle("UNIFIED")
MainForm.RootPane.LoadLayout("1") 'Load the layout file.
MainForm.Show
End Sub
Sub mqtt_Connected (Success As Boolean)
If Success = False Then
Log(LastException)
lblConnectionText.Text = "Not Connected"
Else
lblConnectionText.Text = "Connected"
mqtt.Subscribe(outTopic, 0)
Log("Connected")
Log(" ")
Log("Subscribed to " & outTopic)
End If
End Sub
'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
Return True
End Sub
Sub btnStop_MouseClicked (EventData As MouseEvent)
If mqtt.Connected = False Then Return
mqtt.Publish(outTopic, serializator.ConvertObjectToBytes("s"))
End Sub
Sub btnForward_MouseClicked (EventData As MouseEvent)
If mqtt.Connected = False Then Return
mqtt.Publish(outTopic, serializator.ConvertObjectToBytes("f"))
'mqtt.Publish2(outTopic, serializator.ConvertObjectToBytes("f"),0,False)
End Sub
Sub btnConnect_MouseClicked (EventData As MouseEvent)
Dim clientId As String = Rnd(0, 999999999) & DateTime.Now 'create a unique id
mqtt.Initialize("mqtt", $"tcp://${Host}:${port}"$, clientId)
Dim mo As MqttConnectOptions
mo.Initialize(user, password)
mqtt.Connect2(mo)
End Sub
Sub btnBackwards_MouseClicked (EventData As MouseEvent)
If mqtt.Connected = False Then Return
mqtt.Publish(outTopic, serializator.ConvertObjectToBytes("r"))
End Sub
Sub MainForm_Closed
mqtt.Close
Log("Connection closed")
End Sub