arduino seems to be crashing on a loop

I am hosting a website with a motor control button. the motor is a stepper driven by a DRV8825.

My website always comes up when accessed. When I hit my motor control buttons from the website it will usually drive as expected. After a period of time, this stops working. The website is still hosted and accessible however, the motor will not respond to the html button. When the motor does not drive, I have to reset the Arduino and then everything is happy. I am not sure if the issue is in the code or electronics. Here is my code attached. the website button goes to one or two while loop energized the stepper and then runs the stepper for a specific number of steps either CW or CCW depending on the loop/button. once its done, the line read is cleared.

One partial solution is just to cause the arduino to reset every hour or so. This seems more like a band aid than a fix though.

from an electronics side, I may bring in my multi-meter in to see if I am getting voltage where it should be going but I wanted to check the code first. My setup from an electronics side is as follows. The arduino is powered from a 12v 1.8a power supply. The drv8825 is powered with a 20v 4.5 A PSU. Eventually, I will probably get a step down converter to step down a line from the 20v to power the 20v. That is in the future though.

I essentially have my arduino with ethernet shield connected a drv8825 which is driving a nema 17. I have the sleep and reset pins on the drv8825 seperated to prevent the drv8825 from being constantly
energized.

#include <SPI.h>
#include <Ethernet.h>
#include<SPI.h>
#include<Ethernet.h>
#include <AccelStepper.h>
#define dirPin 8
#define stepPin 9
#define motorInterfaceType 1
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };   //physical mac address
byte ip[] = { 192, 168, 254, 110 };                      // ip in lan (that's what you need to use in your browser. ("192.168.1.178")
byte gateway[] = { 192, 168, 254, 254 };                   // internet access via router
byte subnet[] = { 255, 255, 255, 0 };                  //subnet mask
EthernetServer server(80);                             //server port     
String readString;

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  stepper.setMaxSpeed(2000);
  pinMode(6, OUTPUT);

}

//end setup
void loop() {
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {   
      if (client.available()) {
        char c = client.read();
     
        //read char by char HTTP request
        if (readString.length() < 100) {
          //store characters to string
          readString += c;
          Serial.print(c);
         }

         //if HTTP request has ended
         if (c == '\n') {          
           Serial.println(readString); //print to serial monitor for debuging
           client.println("HTTP/1.1 200 OK"); //send new page
           client.println("Content-Type: text/html");
           client.println();     
           client.println("<HTML>");
           client.println("<HEAD>");
           client.println("<meta name='apple-mobile-web-app-capable' content='yes' />");
           client.println("<meta name='apple-mobile-web-app-status-bar-style' content= 
           'blacktranslucent' />");
           client.println("<TITLE>Sliding Door Opener</TITLE>");
           client.println("</HEAD>");
           client.println("<BODY>");
           client.println("<H1>Let the dogs out!</H1>");
           client.println("<hr />");
           client.println("
");  
           client.println("<H2>Mobile Compatible</H2>");
           client.println("
");  
           client.println("<a href=\"/?button1on\"\">Close Door</a>");
           client.println("<a href=\"/?button3on\"\">Open Door</a>");   
           client.println("
");     
           client.println("
");  
           client.println("<p>Munro household</p>");  
           client.println("
"); 
           client.println("</BODY>");
           client.println("</HTML>");
     
           delay(1);
           //stopping client
           client.stop();
           //controls the Arduino if you press the buttons
           if (readString.indexOf("?button1on") >0){
            stepper.setCurrentPosition(0);
            digitalWrite(6, HIGH);
            delay(200);
            while(stepper.currentPosition() != 50000)
            {
              stepper.setSpeed(800);
              stepper.runSpeed();
              readString="";
              }
              digitalWrite(6, LOW);
            }
            //First while look energizes drv8825 from sleep, runs and puts back to sleep 
           if (readString.indexOf("?button3on") >0){
            stepper.setCurrentPosition(0);
            digitalWrite(6, HIGH);
            delay(200);
            while(stepper.currentPosition() != -50000)
            {
              stepper.setSpeed(-800);
              stepper.runSpeed();
              readString="";
              }
            digitalWrite(6, LOW);  
            readString="";
         }
          //First while look energizes drv8825 from sleep, runs and puts back to sleep
          }}}}}

dooropen_v1.3.ino (3.88 KB)

Did you Read this before posting a programming question ? If so then you did not follow the advice given.

Please help us to help you

added in . thanks. Sorry this is my first post.

John2364:
added in . thanks. Sorry this is my first post.

Thanks for adding the code tags but I see that you have not posted your complete program nor have you Auto Formatted it as recommended

These may not seem important to you, but you need to provide as much assistance as possible to those who can help you otherwise they are likely to move on to another topic

Opps, I missed part of my code when copying. I added it and cleaned up the formatting a bit/added some comments. I did not see any other formatting guidance in the FAQ. Maybe I missed something?

"My website always comes up when accessed. When I hit my motor control buttons, I occasionally cant get the motor to drive. When the motor does not drive, I have to reset the Arduino and then everything is happy. I am not sure if the issue is in the code or electronics."

If the page always refreshes and the serial monitor continues to print out the web request, then that part seems to continue to work, so there might be issues within the motor control loop.

I don't see where you have told us what Arduino you are using.

Code with this sort of thing is almost impossible to make sense of

          }}}}}

Put every } on its own line properly indented to match its {

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

...R

I will reformat ad post back up thanks. its an UNO btw. I think that the string might be the issue. however, If it ran out of memoy due to the string, wouldn’t the whole the website also be unable to process?

I still have to get my multimeter out and see if the Pins are not putting out voltage during the loop.

I have a mild suspicion that it might have to do with putting the drv8825 to sleep and reenergizing it since that is not a common practice in tutorials for this driver.

I posted this earlier in the project guidance form however I am 99.9 percent sure it is a code issue now so I wanted to post it here to see if anyone had ideas.

I am hosting a website that moves a stepper motor based on when each particular button is clicked. the code is posted below. after accessing the site a couple times, it seems to partially crash. The site delivers to the client but the loop stops. I also put in a memory monitor and it does seem to go down on each access down to 1282 but then the loop seems to crash and it stops dropping (pic of serial monitor attached).

I know Strings are not recommended but I am not sure how to read the HTML button with out read.String. I would love to hear any ideas if you think that this is the issue. The loops are on top and the entire code is below it:

Loops

if (readString.indexOf("?button1on") > 0) {
            stepper.setCurrentPosition(0);
            digitalWrite(6, HIGH);
            delay(200);
            while (stepper.currentPosition() != 50000)
            {
              stepper.setSpeed(800);
              stepper.runSpeed();
              readString = "";
            }
            digitalWrite(6, LOW);
          }

          if (readString.indexOf("?button3on") > 0) {
            stepper.setCurrentPosition(0);
            digitalWrite(6, HIGH);
            delay(200);
            while (stepper.currentPosition() != -50000)
            {
              stepper.setSpeed(-800);
              stepper.runSpeed();
              readString = "";
            }
#include <SPI.h>
#include <Ethernet.h>
#include<SPI.h>
#include<Ethernet.h>
#include <AccelStepper.h>
#define dirPin 8
#define stepPin 9
#define motorInterfaceType 1
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };   //physical mac address
byte ip[] = { 192, 168, 254, 110 };                      // ip in lan (that's what you need to use in your browser. ("192.168.1.178")
byte gateway[] = { 192, 168, 254, 254 };                   // internet access via router
byte subnet[] = { 255, 255, 255, 0 };                  //subnet mask
EthernetServer server(80);                             //server port


void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  stepper.setMaxSpeed(2000);
  pinMode(6, OUTPUT);
}


void loop() {


  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();
          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<meta name='apple-mobile-web-app-capable' content='yes' />");
          client.println("<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />");
          client.println("<TITLE>Sliding Door Opener</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");
          client.println("<H1>Let the dogs out!</H1>");
          client.println("<hr />");
          client.println("
");
          client.println("<H2>Mobile Compatible</H2>");
          client.println("
");
          client.println("<a href=\"/?button1on\"\">Close Door</a>");
          client.println("<a href=\"/?button3on\"\">Open Door</a>");
          client.println("
");
          client.println("
");
          client.println("<p>Munro household</p>");
          client.println("
");
          client.println("</BODY>");
          client.println("</HTML>");

          delay(1);
          //stopping client
          client.stop();
          //controls the Arduino if you press the buttons
          if (readString.indexOf("?button1on") > 0) {
            stepper.setCurrentPosition(0);
            digitalWrite(6, HIGH);
            delay(200);
            while (stepper.currentPosition() != 50000)
            {
              stepper.setSpeed(800);
              stepper.runSpeed();
              readString = "";
            }
            digitalWrite(6, LOW);
          }

          if (readString.indexOf("?button3on") > 0) {
            stepper.setCurrentPosition(0);
            digitalWrite(6, HIGH);
            delay(200);
            while (stepper.currentPosition() != -50000)
            {
              stepper.setSpeed(-800);
              stepper.runSpeed();
              readString = "";
            }
            digitalWrite(6, LOW);
            readString = "";
          }
        }
      }
    }
  }
}

            while (stepper.currentPosition() != -50000)
            {
              stepper.setSpeed(-800);
              stepper.runSpeed();
              readString = "";
            }

this loop may never be false;

Topics merged

arduino_new:

            while (stepper.currentPosition() != -50000)

{
              stepper.setSpeed(-800);
              stepper.runSpeed();
              readString = "";
            }




this loop may never be false;

I might be misunderstanding how arduino or C sees the current position of the motor but if it runs to -50k, then it would be false. the motor does stop when it hits this point. I dont know if I mentioned this but the code does work for a bit. The loop does not crash until the page has been sent a couple times. This does not trigger until button 3 is hit either.

is the currentPosition() clamped to -50k?

You might comment out the actual motor control loops and see if the page still stays responsive. Also include printing readString to the serial monittor after it is captured to verify that part of the code is still working when a request is received.

arduino_new:
is the currentPosition() clamped to -50k?

the stepper position changes based on where the motor is. when that loop runs, the motor runs backwards for 50k steps. After that it stops. this piece of the code seems to work fine unless it is continuing to run in the background after.

John2364:
the stepper position changes based on where the motor is. when that loop runs, the motor runs backwards for 50k steps. After that it stops. this piece of the code seems to work fine unless it is continuing to run in the background after.

How do you know if the motor stops at exactly -50k? What if it’s at -49800, then next update -800, it will be at -50600 which is not equal to -50000.

zoomkat:
You might comment out the actual motor control loops and see if the page still stays responsive. Also include printing readString to the serial monittor after it is captured to verify that part of the code is still working when a request is received.

I will try that. Do you think that its index read from the button could be getting screwed up? if so, is there a way to print that to the console to verify what it is seeing?

"Do you think that its index read from the button could be getting screwed up? if so, is there a way to print that to the console to verify what it is seeing?"

You could put a serial print "button3on found" in the if statement if it is detected.

arduino_new:
How do you know if the motor stops at exactly -50k? What if it's at -49800, then next update -800, it will be at -50600 which is not equal to -50000.

you are right. I dont know for a fact that its hitting 50k. I only know it stops at a certain point. I guess its possible something weird could be going on there. Do you think it would be safer to use a >=-50000?

John2364:
you are right. I dont know for a fact that its hitting 50k. I only know it stops at a certain point. I guess its possible something weird could be going on there. Do you think it would be safer to use a >=-50000?

Yes, that would ensure you will always exit the while()