Display Stepper Motor Position in Real Time

Hello Abraham,

I just write to you in private message, because I see that you are an expert of MIT.

First of all forgive me, because I am French, and I use Google translate.
If you don't understand something because of the translation, let me know!

I am a beginner, and I have a project that I am realizing.
Forgive me if I'm using the wrong terms.

I have a Nikon microscope, motorized on 3 axes: XYZ.

The original control box has given up the ghost... (the Z axis).

I am changing everything (nema 17 motor, Arduino mega control box)

And so I wanted to develop a mobile application to control all of these and add other functions.

I then discovered MIT APP, and I started to learn how to use it.

As you can see in the attached photo, I would like to display the position of the stepper motor in real time.

On Arduino, I use the "StepperAccel" library. Inside this library, there is a ready-made function to return the position of the motor (stepper.currentPosition();).

But when I wanted to display this position on MIT APP (in a Label), it produced something weird…

To illustrate my problem, I made a very basic application, with very basic Arduino code.

I would like to display the value of a potentiometer (Nikon microscope joystick).

I got there, but it produces the same problem...

The Label is transformed into a kind of table filled with values, and often the first value disappears...

It's not easy to explain in words, so I'm sharing some screenshots, and I'll also try to share a video.

Maybe help me?

I thank you in advance ! :slight_smile:




I made your post public.

You need:

  • people with hardware experience
  • people who can read French
  • a broad range of time zones
  • an audience, in a learning community

This board can supply that much better than little old me.

What is the DelimiterByte in Bluetooth?
What clock interval do you use?
To test, receive the data as text, set a slower Arduino delay, delay(1000).
Check in this Community topics about Bluetooth.

Edit: Here is an example with a small Stepper Motor, in this case information is sent from the App to the Arduino.
Bluetooth HC-06. Arduino. Send. Receive. Send text file. Multitouch. Image - #14 by Juan_Antonio

Hello,

thank you for your reply.

MIT's current DelimiterByte is currently 0 (I admit I don't know what it's for yet)
How to receive data as text?

Thanks for the links, I'll go check it out.

Hi there,

Searching the internet, I found the solution.

I am sharing MIT blocks with Delimiter Byte value at 10 + Arduino code.

I haven't tried to display the position of a stepper motor yet.

But apparently after a quick test, it works very well for me to display the value of a potentiometer. :slight_smile:


1 Like

Hello,

I managed to display the steps of a stepper motor in a label.

I am sharing some picture and video if it can help anyone.

However, one problem chases another...

In my Arduino code, I'm forced to put two things in there:

bluetooth.println(messageBT);
delay (…);

My new problem is that the addition of these two things slows down, see practically stops the rotation of the motor...

If someone has an idea…

I use the AccelStepper library.


Capture d’écran 2022-06-08 154457

From the experience of others with this problem, the recommended solution is to replace the delay() call with an extra variable, Last_Time_Transmitted_ms, which would hold the last System Time in Milliseconds from 1970 (default 0) when the Arduino issued a BlueTooth println(). In the loop(), each cycle you should check if (Current SystemTime in ms) - Last_Time_Transmitted_ms > 25 (whatever your delay was) .

If the difference > 25, do your println and reset the Last_Time_Transmitted_ms to (Current SystemTime in ms), else do nothing.

P.S. 25 ms might be too frequently for AI2 to handle.

1 Like

(added to FAQ)

(added to FAQ)

Thank you for this lead, I will explore it. :slight_smile:

Like this:

unsigned long lgUpdateTime;

void setup()
{
               lgUpdateTime = millis();
}

void loop()
{
	           if(millis() - lgUpdateTime > 100)      //Loop approx every 100 milliseconds
               {
                         lgUpdateTime = millis();

                         //everything else here

               }
}

Thank you for your answers.

Putting in a "millis" instead of a "delay" pretty much fixed the issue.

I share the code snippet that worked for me:


if (millis() - lgUpdateTime > 100) //Loop approx every 100 milliseconds
{
lgUpdateTime = millis();

  messageBT = (String) pasMoteurZ + "," + (String) pasMoteurY + "," + (String) pasMoteurX;

  Serial.println(messageBT);
  bluetooth.println(messageBT);

}


However, we feel a (I don't know how to translate this word in English... in French: "à-coup", in English maybe "jerk", it's a slight delay, as if the code stops a few millis ) in the rotation of the motor every 100 millis.

I think (not sure) it came from the line: messageBT = (String) pasMotorZ + ", […]

Because for example when I write a single String (pasMoteurZ), the jerk is weak, and the more Strings I add (like pasMoteurY, pasMoteurX, …), the jerk is stronger and stronger…

I don't know if I was very clear in my explanations, don't hesitate to ask me for more information :slight_smile:

Do you have an idea ?

Does Serial.println() block further code until it has finished?

Is there an asynchronous alternative, like buffering println() requests and having the buffer serviced through another process?

Maybe - strings should not be assembled at the microcontroller end, just send values to the App directly. If the values are arriving in the App and are as expected, comment-out the data send to the Arduino Serial Monitor, that alone will make a difference.

If the values are floats, use Serial to limit the decimal places.

Send the data to the App like so:

bluetooth.print(pasMoteurX);
bluetooth.print(",");
bluetooth.print(pasMoteurY);
bluetooth.print(",");
bluetooth.print(pasMoteurZ)
bluetooth.println(); //empty. tells App "End of Data" = LineFeed Ascii Char N° 10

I always recommend using the bar "|" as the value separator as it is most unlikely to be within a value and it's simply easier to see in the code, especially App Inventor code.

Also, with your Arduino loop set @ 100 milliseconds, Your App Clock Timer interval should be 80 milliseconds.

Hello,
thank you for your different answers.

I tried removing the :

I also tried as a replacement with this piece of code:

But unfortunately it still produces a microstop every 100 milliseconds.

However, this micro stop remains very light, and I don't think it will be a problem for the rest of my project.

Thank you all for your help! :slight_smile:

You can tweak the Sketch time interval and the App time Interval, maintaining the 20% difference - For example, try 60 milliseconds in the Sketch and 48 milliseconds in the App.