1

I have this code running in STM32F469 DISCO KIT: https://github.com/neuberfran/discovery7/blob/main/applications/lvgl/demo/ui/ui_events.cpp

The lib SmartDrive Makes the motor run for 5 seconds (by default). When I want to stop the motor before that time, I click the stop button it works ok. Or else the motor stops by itself in 5s

But, when I want the motor to run for more than 5 seconds I need to put this routine: smd.Run_Unlimited(SmartDrive_Motor_ID_1, SmartDrive_Dir_Reverse, 90); in While - Loop.

At that moment my issue enters because I am not able to stop the motor through the code below. Does anyone have any tips on how to resolve this? Would I have to use interrupt? Would I have to use another task? How to use?

New ui_events.cpp File with issue:

#include <Arduino.h>
#include "ui.h"
#include <SmartDrive.h>

SmartDrive smd = SmartDrive(SmartDrive_DefaultAddress);

bool STOP01 =  true;
#define STOP02  0

void run01right(lv_event_t * e)
{
    // Your code here
    while (STOP01)
    {
    smd.Run_Unlimited(SmartDrive_Motor_ID_1, SmartDrive_Dir_Reverse, 90);
    }
    STOP01 = true;
}


void stopmotor01(lv_event_t * e)
{
    // Your code here
    STOP01 = false;
    smd.StopMotor(SmartDrive_Motor_ID_1, SmartDrive_Action_Brake);
    STOP01 = true;

}

void run01left(lv_event_t * e)
{
    // Your code here
    while (STOP01)
    {
    smd.Run_Unlimited(SmartDrive_Motor_ID_1, SmartDrive_Dir_Forward, 90);
    }
    STOP01 = true;
}

Note: As the First photo below, it is not possible to implement void loop in this case. 2022-09-09 <-> I was wrong. It is possible to implement void setup() and void loop() and it was done. And so it resolved

enter image description here enter image description here

neuberfran
  • 359
  • 3
  • 18
  • 2
    By referring to _"interrupt (or task)"_ you are making this and X-Y problem. That is a question about your solution rather then a question about the problem you are trying to solve. Generally it is better to ask about the problem and get a range of solutions than to ask how to implement a possibly flawed, unnecessarily complex or impossible solution. – Clifford Aug 23 '22 at 08:07
  • 2
    You could use a timer interrupt rather than the `loop()` and the body would look much like that of the `loop()` in my answer - If you have other stuff to do in `loop()` that is perhaps non-deterministic or busy-waits, then that might be a solution, but a good `loop()` design should not do that, and my answer is an example of how to avoid it. – Clifford Aug 23 '22 at 14:52
  • 2
    All I am saying is that you should explain the problem - your inability to schedule both the UI and motor control simultaneously, rather then asking how to implement a specific solution. Also always better to post code rather then a _picture_ of your code. – Clifford Aug 23 '22 at 14:55

1 Answers1

1

In the Arduino Sketch setup()/loop() framework it is ill advised to have "busy-loops" withing loop(). Instread you should us eretained state information to determine what should happen for each loop() iteration. The real-time behaviour and responsiveness to external events will then be more deterministic.

So you might have:

enum
{
    RUN_LEFT,
    RUN_RIGHT,
    STOP
} motor_state_01, motor_state_02 ;


void run01left(lv_event_t * e)
{
    motor_state_01 = RUN_LEFT ;
}

void run01right(lv_event_t * e)
{
    motor_state_01 = RUN_RIGHT ;
}

void stopmotor01(lv_event_t * e)
{
    motor_state_01 = STOP ;
}

void loop()
{
    switch( motor_state_01 )
    {
        case RUN_RIGHT :
        {
            smd.Run_Unlimited( SmartDrive_Motor_ID_1, 
                               SmartDrive_Dir_Reverse, 90);
        }
        break ;
        case RUN_RIGHT :
        {
            smd.Run_Unlimited( SmartDrive_Motor_ID_1, 
                               SmartDrive_Dir_Forward, 90);
        }
        break ;
        case STOP :
        {
            smd.StopMotor( SmartDrive_Motor_ID_1, 
                           SmartDrive_Action_Brake );
        }
        break ;
    }
}

So that now you have a single non-blocking loop where the actions in each iteration depend on the state information set by the UI event handlers. The UI event handlers themselves do no "busy" work to ensure both the responsiveness of the UI and real-time control of the motor.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • 1
    Thanks for answering. This is what I needed. Give me an option to resolve my issue. But in my sketch (.cpp file) there is no void setup()/void loop() yet. I still don't know how to implement it( void setup()/void loop() - Look to pic above. I will try your suggestion later today. I'll also try to create one more variable that would be inside the while and would be updated inside the stop button function. – neuberfran Aug 23 '22 at 12:08
  • 2
    @NEUBERSOUSA : Are you using Arduino or not? You tagged it thus. The Arduino environment provides a `setup()`/`loop()` for you and "hides" `main()` from you. It does not really matter much; what Arduino's `main()` does is repeatedly call a function called `loop()` after performing initialisation of itself and the application via `setup()`; you can do that yourself without the whole Arduino framework. – Clifford Aug 23 '22 at 15:01
  • 2
    @NEUBERSOUSA you appear to be a different user than that who posted the question. – Clifford Aug 23 '22 at 15:05
  • 1
    @Clifford Friend. Thanks for your interest. I don't know if you've used LVGL, but in this case (As I did) just rename the file ui_events.c to ui_events.cpp and everything works. – neuberfran Aug 23 '22 at 15:14
  • 1
    @Clifford https://www.youtube.com/watch?v=MAr3F34bJsk As you can see in this video, if I send the command smd.Run_Unlimited(SmartDrive_Motor_ID_1, SmartDrive_Dir_Reverse, 90); outside the loop the motor only spins 5 seconds (default). But if before 5s I command stop via (ui_events.cpp) the motor stops. – neuberfran Aug 23 '22 at 15:18
  • 1
    @Clifford https://forum.squareline.io/t/how-can-i-use-mqtt-in-lvgl/153/5 This is the site that solved the first part of my problem which was to implement arduino commands in RT-Thread Os in a practical and easy way. You would have to look at the project's github (discovery7) to understand the whole application/LVGL usage – neuberfran Aug 23 '22 at 15:33
  • 1
    @Clifford I'm using RTduino. A lib inside RT-Thread Os that "simulates arduino" https://github.com/neuberfran/discovery7/blob/main/applications/lvgl/demo/ui/ui_events.cpp – neuberfran Aug 23 '22 at 15:35
  • @neuberfran Ok -seems like a backward step to simulate a "big-loop" scheduler in an RTOS. Or does this just provide an arduino-like library, without the executive framework? Either way it is mis-tagged [Arduino]. – Clifford Aug 23 '22 at 15:55
  • 1
    @Clifford https://github.com/neuberfran/discovery7/blob/main/applications/arduino_main.cpp https://github.com/neuberfran/discovery7/blob/main/packages/LVGL-v8.3.1/examples/arduino/LVGL_Arduino/LVGL_Arduino.ino As you can see in these links above, the project includes 2 files suitable for arduino. But I'm not using them. RTduino is great for implementing my lib (SmartDrive) on my STM32F469 kit disco with RT-Thread OS. The first one I'm not using because it makes it difficult to integrate the LVGL ui files with the arduino/project. The second, logs do not appear at all in my Console. – neuberfran Aug 23 '22 at 16:27
  • I would guess that you could replace the delay with the code in my answer, if you are running other threads, you will still need to block or yield, but I would hope the "simulator" would do that before/after loop(). Arduino is not really a good fit for an RTOS, and there is a lot of very poor Arduino code - even in the project's own examples. Nonetheless, I hope you appreciate that your question as it is is incomplete and misleading, making it somewhat difficult to answer. – Clifford Aug 24 '22 at 05:29
  • 1
    @Clifford My question and other explanations below it are neither confusing nor misleading. If you can't answer in a way that solves it, it's not my fault. – neuberfran Aug 24 '22 at 15:22
  • Indeed your further explanation in comments serve to clarify somewhat. But in SO the question should be able to stand on its own. I. The question. You do not mention RTduino or RT-Thread and misleadingly tagged it Arduino. Really though you are hardly the arbiter of the question's clarity - that is a matter for the audience. It the answer I provided in does not work, that will be because you there is something missing from your question. That is the "Arduino-like" solution, which as posed is all you can expect from your question. – Clifford Aug 24 '22 at 19:36
  • @Clifford OK. I respect your opinion. But, I don't see why not put the tag [Arduino] in 1 project that uses code and arduino header/compatible. And that the issue happens within that part of the project. – neuberfran Aug 25 '22 at 15:34
  • This discussion is veering off-topic, it is becomming about question quality. The issue is not including [arduino] but rather about _not_ reveailig your true environment - information that may be relevant to the answer. If you tag it [arduino] it is reasonable yo assume you are using the arduino framework, but the forst response to my answer was that you had no setup/loop (even though you showed an _image of code_ - a bad thing in it self - that clearly has a `loop()` function). – Clifford Aug 25 '22 at 19:14
  • The point is that this answer is the way you would do it on an Arduino, so given the tagging and information available, this is a reasonable answer. If it did not solve your problem, that is because of lack of information on your part. Possibly the integration of LVGL is done in such a way that it that it defeats your motor control. Given an RTOS (not revealed in the question) I would run the LVGL in a separate thread to the arduino framework, and probably not use the Arduino framework at all. You are doing RTOS wrong if you think the Arduino paradigm is appropriate. – Clifford Aug 25 '22 at 19:19
  • @Clifford https://forum.arduino.cc/t/how-to-implement-interrupt-or-task-inside-while-loop-in-cpp-file-without-void-loop/1025352/9 – neuberfran Aug 25 '22 at 23:43
  • Unlike the link you posted (and I have not followed) SO is not a discussion forum. Both questions and answers should be complete and useable in their own without the comments. I would advise in future helping those trying to help you rather than assuming that you have provided all necessary information in the first instance. – Clifford Aug 26 '22 at 05:41