kakopappa / sinric

Amazon Alexa Smart home skill / Google Home Action for ESP8266 / ESP32 / Arduino
https://sinric.com
287 stars 166 forks source link

integrate a piece of code for a stepper motor #340

Open diepie opened 5 years ago

diepie commented 5 years ago

In the Sinric Switch sample code ( switch_example.ino -> https://github.com/kakopappa/sinric/blob/master/arduino_examples/switch_example.ino ) I have to integrate a piece of code for a stepper motor that needs to loop, after device ID 1 is true, so after this line:

void turnOn(String deviceId) { if (deviceId == "5cf8de1d0837cc3a87c8faf5") // Device ID of first device

This Is The piece of code that has to loop:

void loop() {

//Change direction when the stepper reaches the target position if (stepper1.distanceToGo() == 0) { stepper1.moveTo(-stepper1.currentPosition()); } stepper1.run(); }

Question Is Where do I have to put this peace of code so that it loops, i cannot have to instances of void loop()

Regards Peter

kakopappa commented 5 years ago

what are trying to do ? turn on the stepper motor? You can't have a loop inside void turnOn(String deviceId) ...

I dont understand what are you tyring to do here. So i am going to guess based on a command you receive, you are trying to move the stepper

bool moveStepper = false;

void turnOn(String deviceId) { if (deviceId == "5cf8de1d0837cc3a87c8faf5") // Device ID of first device { moveStepper = true; } }

void loop() { .... if(moveStepper == true) { moveStepper = false;

if (stepper1.distanceToGo() == 0) { stepper1.moveTo(-stepper1.currentPosition()); }

} stepper1.run(); } }

diepie commented 5 years ago

thanks, i'm going to try and come back to it soon

diepie commented 5 years ago

The complete code with your proposal is pasted below. The problem is still that the piece of code that the stepper motor has to run is only executed once when it is switched on. This code must loop until the current Position is reached

include

include

include

include // https://github.com/kakopappa/sinric/wiki/How-to-add-dependency-libraries

include // https://github.com/kakopappa/sinric/wiki/How-to-add-dependency-libraries

include

include

define HALFSTEP 8

ESP8266WiFiMulti WiFiMulti; WebSocketsClient webSocket; WiFiClient client;

define MyApiKey "4983cfee-24ef-4b82-b0b1-9dc43ac9e057" // TODO: Change to your sinric API Key. Your API Key is displayed on sinric.com dashboard

define MySSID "*****" // TODO: Change to your Wifi network SSID

define MyWifiPassword "****" // TODO: Change to your Wifi network password

// Motor pin definitions

define motorPin1 5 // IN1 on the ULN2003 driver 1

define motorPin2 4 // IN2 on the ULN2003 driver 1

define motorPin3 0 // IN3 on the ULN2003 driver 1

define motorPin4 2 // IN4 on the ULN2003 driver 1

// Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48 AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);

define HEARTBEAT_INTERVAL 300000 // 5 Minutes

const int relayPin = D1;

uint64_t heartbeatTimestamp = 0; bool isConnected = false;

void setPowerStateOnServer(String deviceId, String value); void setTargetTemperatureOnServer(String deviceId, String value, String scale);

// deviceId is the ID assgined to your smart-home-device in sinric.com dashboard. Copy it from dashboard and paste it here

bool moveStepper = false;

void turnOn(String deviceId) { if (deviceId == "5cf8de1d0837cc3a87c8faf5") // Device ID of first device { Serial.print("Turn on device id: "); Serial.println(deviceId);

digitalWrite(relayPin, HIGH); // turn on relay with voltage HIGH

moveStepper = true;

} else { Serial.print("Turn on for unknown device id: "); Serial.println(deviceId); } }

void turnOff(String deviceId) { if (deviceId == "5cf8de4d0837cc3a87c8faf7") // Device ID of first device { Serial.print("Turn off Device ID: "); Serial.println(deviceId);

digitalWrite(relayPin, LOW);  // turn off relay with voltage LOW

} else { Serial.print("Turn off for unknown device id: "); Serial.println(deviceId); } }

void loop() {

webSocket.loop();

if (isConnected) { uint64_t now = millis();

if ((now - heartbeatTimestamp) > HEARTBEAT_INTERVAL) {
  heartbeatTimestamp = now;
  webSocket.sendTXT("H");
}

}

if (moveStepper == true) { moveStepper = false;

if (stepper1.distanceToGo() == 0) {
  stepper1.moveTo(-stepper1.currentPosition());
}
stepper1.run();

} } //end loop

void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { switch (type) { case WStype_DISCONNECTED: isConnected = false; Serial.printf("[WSc] Webservice disconnected from sinric.com!\n"); break; case WStype_CONNECTED: { isConnected = true; Serial.printf("[WSc] Service connected to sinric.com at url: %s\n", payload); Serial.printf("Waiting for commands from sinric.com ...\n"); } break; case WStype_TEXT: { Serial.printf("[WSc] get text: %s\n", payload); // Example payloads

    // For Switch or Light device types
    // {"deviceId": xxxx, "action": "setPowerState", value: "ON"} // https://developer.amazon.com/docs/device-apis/alexa-powercontroller.html

    // For Light device type
    // Look at the light example in github

    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.parseObject((char*)payload);
    String deviceId = json ["deviceId"];
    String action = json ["action"];

    if (action == "setPowerState") { // Switch or Light
      String value = json ["value"];
      if (value == "ON") {
        turnOn(deviceId);
      } else {
        turnOff(deviceId);
      }
    }
    else if (action == "SetTargetTemperature") {
      String deviceId = json ["deviceId"];
      String action = json ["action"];
      String value = json ["value"];
    }
    else if (action == "test") {
      Serial.println("[WSc] received test command from sinric.com");
    }
  }
  break;
case WStype_BIN:
  Serial.printf("[WSc] get binary length: %u\n", length);
  break;

} }

void setup() { Serial.begin(115200);

stepper1.setMaxSpeed(1000.0); stepper1.setAcceleration(100.0); stepper1.setSpeed(200); stepper1.moveTo(20000);

// Relay PIN eg: https://github.com/wemos/D1_mini_Examples/blob/master/examples/04.Shields/Relay_Shield/Blink/Blink.ino pinMode(relayPin, OUTPUT);

WiFiMulti.addAP(MySSID, MyWifiPassword); Serial.println(); Serial.print("Connecting to Wifi: "); Serial.println(MySSID);

// Waiting for Wifi connect while (WiFiMulti.run() != WL_CONNECTED) { delay(500); Serial.print("."); } if (WiFiMulti.run() == WL_CONNECTED) { Serial.println(""); Serial.print("WiFi connected. "); Serial.print("IP address: "); Serial.println(WiFi.localIP()); }

// server address, port and URL webSocket.begin("iot.sinric.com", 80, "/");

// event handler webSocket.onEvent(webSocketEvent); webSocket.setAuthorization("apikey", MyApiKey);

// try again every 5000ms if connection has failed webSocket.setReconnectInterval(5000); // If you see 'class WebSocketsClient' has no member named 'setReconnectInterval' error update arduinoWebSockets }

// If you are going to use a push button to on/off the switch manually, use this function to update the status on the server // so it will reflect on Alexa app. // eg: setPowerStateOnServer("deviceid", "ON")

// Call ONLY If status changed. DO NOT CALL THIS IN loop() and overload the server. void setPowerStateOnServer(String deviceId, String value) { DynamicJsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.createObject(); root["deviceId"] = deviceId; root["action"] = "setPowerState"; root["value"] = value; StreamString databuf; root.printTo(databuf);

webSocket.sendTXT(databuf); }

//eg: setPowerStateOnServer("deviceid", "CELSIUS", "25.0")

// Call ONLY If status changed. DO NOT CALL THIS IN loop() and overload the server. void setTargetTemperatureOnServer(String deviceId, String value, String scale) { DynamicJsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.createObject(); root["action"] = "SetTargetTemperature"; root["deviceId"] = deviceId;

JsonObject& valueObj = root.createNestedObject("value"); JsonObject& targetSetpoint = valueObj.createNestedObject("targetSetpoint"); targetSetpoint["value"] = value; targetSetpoint["scale"] = scale;

StreamString databuf; root.printTo(databuf);

webSocket.sendTXT(databuf); }

JanB97 commented 5 years ago

Hi, without reading your whole code... Remove "moveStepper = false;" after "if(moveStepper == true) {" and put it in an if statement that only gets executed after the posisition is reached. The loop will run until "moveStepper" is false, so don't set it to false if you want to move the stepper further.

This really has nothing to do with sinric though, it's simple arduino programming, you would be better of posting this in an arduino forum.