Hi, I tried to program with arduino a stepper motor with Nextion display.
The program that I made work fine but the problem is when I tried to send the position of the stepper to the Nextion display each 1s to update it using Serial.print the code blocks maybe 10ms or something like this, and this make the stepper blocks a little when it is running.
To control the motor I am using the accelStepper library.
So my question is if there are any posibility to solve this issue and make the delay in Serial.print 0ms or this is imposible as the function needs this time to execute.
Please post your full sketch, using code tags when you do. Posting the sketch will enable us to see things such as the Serial baud rate that you are using, which should be as fast as possible
My crystal ball shows @ingyou is using software serial on an Uno to communicate to the display, making the problem described inevitable.
If correct, @ingyou needs to remember that most Arduino have only one CPU core and cannot truly perform more than one task at the same instant in time, such as driving a stepper motor and sending serial data to another device. What some Arduino do have is timer and UART circuits built into the chip which can perform their tasks independently of the CPU. If you can use those circuits, having only one CPU is no longer such a problem.
For example, with some stepper motor drivers, only 2 pins are required for DIRECTION and STEP. With this type, a timer circuit in the arduino can be used to send regular pulses to the STEP pin, freeing the CPU to communicate with the display.
Some types of Arduino have extra hardware UART ports (hardware serial) which could communicate to the display, freeing the CPU to drive the stepper motor.
The solution to this problem is to use a different stepper-library.
This library is called MobaTools and can be installed with the Arduino-IDE-library-manager.
The MobaTools use a different approach to create the step-pulses:
The step-pulses are created by a timer-interrupt. This means the step-pulses are created in the backround just-in-time for a smooth running stepper-motor.
If you have installed the library a PDF-documentation in english and in german is also stored in the MobaTools-subfolder. Ask here in the forum. Post your code but
If you have any problems in applying / modifying one of the example codes
important !
post your code as a code-section like described here
But if my crystal ball is reading correctly and @ingyou is using software serial to communicate to the display, software serial library may disable interrupts so that it can send data correctly?
If you have any question about a demo-code ask the questions here in the forum
once you have learned how the library works it offers a lot of comfort for doing things
much easier as coding them from scratch by hand
It's a round about way of saying that there were some important facts you could have included in your original post that would have removed the need for forum members to take guesses.
Yes, you are right. The sound of the motor is better than using accelStepper library.
Finally it WORKED fine and the stepper doesn't blocks anymore. But now there is a little problem with other thing.
If I push or released the button at the same time when it is sending the data to display, it not detect the "change" because arduino is "busy" sending data. Here is what I did.
if((millis()-timeReleased2) >= 200)
{
float calcAngleAxis1 = ((myStepper.currentPosition()*360.00)/1600)/8; //gearbox is x8
grM1.setText(dtostrf(calcAngleAxis1, 5, 2, angleAxis1));
//This is what the library nextion does to send text to the display.
//Serial2.print("grM1.txt=\""); Serial2.print(angleAxis1).toFloat()); Serial2.print("\"");
//Serial2.write(0xff); Serial2.write(0xff); Serial2.write(0xff);
timeReleased2 = millis();
}
And I have another question. In this library is Multisteppers function like accelStepper?
without the whole sketch I can't analyse what you have coded.
The mobaTools also offer functions for detecting buttons.
I haven't used the button-functions much but as the mobaTools were coded by a modelrailway enthusiast I guess that the mobatools button-functions work well together with the stepper-functions
No the nextion-display is connected with a serial interface.
The only thing a nextion-button has in common with a physical button is the name.
Everything else is different between nextion "buttons" and real physical buttons.
As a general hint: you will finish your project 5 hours faster if you always invest 5 minutes more to write detailed postings instead of short messages.
This is not WhatsApp, nor instagram nor snapchat for fun.
This is serious software-developping
Switch over and get used to detailed writing
I haven't used nextion displays much.
When I used I did not use the nextion-library
I read in the data sended from the nextion display straight forward directly from the serial interface and this worked very well in parallel with using stepper-motors.
best regards Stefan
I am sorry if I have not done it correctly, I know this is serious software-developping. It is my first post and I have tried to be as clear as possible.
There are other doubts that have been arising so I have been publishing/asking them.
I will try to get the data from the nextion display directly from the serial port.
Thank you very much for your help.
Yes exactly, is not recognised.
Like I said: If I push or released the button at the same time when it is sending the data.
If I press the button while the code is executing this line of code (I attached it below), arduino does not recognise the state change of display-button in this precise moment.
void sendCommand(const char* cmd)
{
while (nexSerial.available())
{
nexSerial.read();
}
the sendcommand-function
void sendCommand(const char* cmd)
{
while (nexSerial.available())
{
nexSerial.read(); // <<= take byte out of the receive buffer and throw away
}
nexSerial.print(cmd);
nexSerial.write(0xFF);
nexSerial.write(0xFF);
nexSerial.write(0xFF);
}
when the sendCommand-function is called and right in that moment
if there are some bytes in the receive-buffer
then before sending a command
the function it reads from the serial receivebuffer and just throws away the received bytes.
don't know what the developper of this code thought what he is doing here.
So I guess if you switch over to direct serial-send and serial-receive it should work
You could try changing the baudrate from 9600 baud to 115200 baud
with the command bauds=115200
where bauds saves the baudrate to be the new standardbaudrate
For a more effective way of communicating you can use shorter commands
like "< B 1 >"
The meaning of the characters is
"<" start-character indicating a command starts
"B1" identifier to know which Nextion-element is pressed
">"-end-character indicating the end of a command
This requires a serial-receive-function that uses start and end characters
the serial receiving with start / endmarker works this way
// fetch data from receivebuffer
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
// if bytes are inside the receivebuffer .available() > 0
// .available() delivers the number of bytes in the buffer
while (Serial2.available() > 0 && newData == false) {
rc = Serial2.read();
if (recvInProgress == true) { // if startmamrker is found set flag
if (rc != endMarker) { // if byte in variable "rc" is NOT the Endmarker
receivedChars[ndx] = rc; // append byte in variable "rc to end of array
ndx++; // increment indexcounter
if (ndx >= numChars) { // if byteseqwuence is too long
ndx = numChars - 1; // reduce indexcounter throw away the byte
}
} // if (rc != endMarker) {
else {
receivedChars[ndx] = '\0'; // terminate the string with trailing zero
recvInProgress = false; // set flag message received finished
ndx = 0;
newData = true; // set flag command received completely
}
} // if (recvInProgress == true) {
else if (rc == startMarker) { // if Byte in variable "rc" is the startmarker
recvInProgress = true; // set boolean flag
}
} // while (Serial2.available() > 0 && newData == false) {
}
in your main loop you check if variable newData is true
if true
command is received completely and can be evaluated
and after copying the command from receive-array immidiately set newData to false to make receive-function ready to receive the next command