Dear all,
i set up a smarthome awning control.
Components:
- ESP8266
- BTS7960
- Hall Sensor
- 12V DC motor
The DC motor is able to rotate clockwise and counterclockwise via the H-Bridge.
Commands are triggered via MQTT.
Rotations are counted via Hall Sensor.
However i do have a problem: When i start up the ESP8266 (or flash or reset it) the DC motor is immediately rotating for ~5 second. Then it stop and everything works from there on.
PWM pins are D3 (pin_pwm_pos) and D4 (pin_pwm_neg).
How can i inhibit these first 5 second rotations?
Code below:
#include <Arduino.h>
#include <assert.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
const char* ssid = "XXXXX";
const char* password = "XXXXX";
const char* mqtt_server = "XXXX";
const int mqttPort = 1883;
const char* mqttUser = "XXXX";
const char* mqttPassword = "XXXXX";
WiFiClient espClient;
PubSubClient client(espClient);
const int pin_pwm_pos = 0; //D3
const int pin_pwm_neg = 2; //D4
//const int pin_ena_pos = 16; //D0
//const int pin_ena_neg = 5; //D1
int rotation_direction = 0;
int rotation_speed = 100;
int rotation_pwm = rotation_speed * 10.23;
int max_rotation = 10;
int target_percentage = 0;
int target_rotation = 0;
int actual_percentage = 0;
int max_rotation_duration = 2000; //ms
const uint8_t interruptPin = 5; //D1
volatile byte interruptCounter = 0;
volatile unsigned int isrMillis;
volatile unsigned int duration = 0; //ms
int numberOfInterrupts = 0;
//int rpm = 0;
volatile unsigned int timeold;
void ICACHE_RAM_ATTR handleInterrupt();
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void MQTTCallback(char* topic, byte* payload, unsigned int length) {
String PayloadString = "";
for (int i = 0; i < length; i++) {
PayloadString = PayloadString + ( char)payload[i];
}
Serial.println("New message arrived");
Serial.println(topic);
Serial.println(PayloadString);
if (strcmp(topic, "ArduinoMarkise/cmnd/direction") == 0) {
Serial.println("set new direction");
rotation_direction = PayloadString.toInt();
if (rotation_direction == 0) {
client.publish("ArduinoMarkise/fb/log", "Rotation direction 0 recieved");
}
}
if (strcmp(topic, "ArduinoMarkise/cmnd/speed") == 0) {
Serial.println("set new speed");
rotation_speed = PayloadString.toInt();
rotation_pwm = rotation_speed * 10.23;
}
if (strcmp(topic, "ArduinoMarkise/cmnd/max_rotation") == 0) {
Serial.println("set new max rotation");
max_rotation = PayloadString.toInt();
}
if (strcmp(topic, "ArduinoMarkise/cmnd/target_percentage") == 0) {
Serial.println("set new target_percentage");
target_percentage = PayloadString.toInt();
target_rotation = target_percentage / 100 * max_rotation;
}
}
void reconnect() {
while (!client.connected()) {
// Create a random client ID
String clientId = "ESP8266Casdlient-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println("subscribe objects");
client.subscribe("ArduinoMarkise/cmnd/direction");
client.subscribe("ArduinoMarkise/cmnd/speed");
client.subscribe("ArduinoMarkise/cmnd/max_rotation");
client.subscribe("ArduinoMarkise/cmnd/target_percentage");
client.publish("ArduinoMarkise/cmnd/target_percentage", 0);
client.publish("ArduinoMarkise/fb/actual_percentage", 0);
}
else
{
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
pinMode(pin_pwm_pos, OUTPUT);
pinMode(pin_pwm_pos, OUTPUT);
analogWrite(pin_pwm_pos, 0);
analogWrite(pin_pwm_neg, 0);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(MQTTCallback);
ArduinoOTA.setHostname("Markise_control");
ArduinoOTA.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH) {
type = "sketch";
} else { // U_FS
type = "filesystem";
}
// NOTE: if updating FS this would be the place to unmount FS using FS.end()
Serial.println("Start updating " + type);
});
ArduinoOTA.onEnd([]() {
Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) {
Serial.println("Auth Failed");
} else if (error == OTA_BEGIN_ERROR) {
Serial.println("Begin Failed");
} else if (error == OTA_CONNECT_ERROR) {
Serial.println("Connect Failed");
} else if (error == OTA_RECEIVE_ERROR) {
Serial.println("Receive Failed");
} else if (error == OTA_END_ERROR) {
Serial.println("End Failed");
}
});
ArduinoOTA.begin();
Serial.println("Ready");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
pinMode(interruptPin, INPUT);
attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);
}
void handleInterrupt() {
if (rotation_direction == 1) {
interruptCounter++;
} else if (rotation_direction = -1) {
interruptCounter--;
}
isrMillis = millis();
}
void loop() {
if (!client.connected()) {
reconnect();
}
ArduinoOTA.handle();
client.loop();
if (rotation_direction == 0) {
isrMillis = millis();
}
timeold = millis();
duration = timeold-isrMillis;
if (duration > max_rotation_duration) {
rotation_direction = 0;
analogWrite(pin_pwm_pos, 0);
analogWrite(pin_pwm_neg, 0);
client.publish("ArduinoMarkise/cmnd/direction", 0);
client.publish("ArduinoMarkise/fb/log", "Duration exceeded");
}
switch (rotation_direction) {
case 1:
if (interruptCounter >= target_rotation) {
rotation_direction = 0;
analogWrite(pin_pwm_pos, 0);
analogWrite(pin_pwm_neg, 0);
client.publish("ArduinoMarkise/cmnd/direction", 0);
client.publish("ArduinoMarkise/fb/log", "Positive target position reached");
} else {
analogWrite(pin_pwm_pos, rotation_pwm);
analogWrite(pin_pwm_neg, 0);
client.publish("ArduinoMarkise/fb/log", "Positive rotation direction");
}
actual_percentage = ( interruptCounter * 100 ) / max_rotation ;
client.publish("ArduinoMarkise/fb/actual_percentage", String(actual_percentage).c_str());
break;
case -1:
if (interruptCounter == 0) {
rotation_direction = 0;
analogWrite(pin_pwm_pos, 0);
analogWrite(pin_pwm_neg, 0);
client.publish("ArduinoMarkise/cmnd/direction", 0);
client.publish("ArduinoMarkise/fb/log", "Target position 0 reached");
} else {
analogWrite(pin_pwm_pos, 0);
analogWrite(pin_pwm_neg, rotation_pwm);
client.publish("ArduinoMarkise/fb/log", "Negative rotation direction");
}
actual_percentage = ( interruptCounter * 100 ) / max_rotation ;
client.publish("ArduinoMarkise/fb/actual_percentage", String(actual_percentage).c_str());
break;
case 0:
analogWrite(pin_pwm_pos, 0);
analogWrite(pin_pwm_neg, 0);
duration = 0;
break;
}
delay(100);
}