8 years, 1 month ago.

Strange behavior

I am using a ticker to move a stepper and there is something very strange happening that I cant find why. Can someone please take a look and help me? (Disregard the portions concerned with TFT output)

My code is

#include "mbed.h"
#include "TFT_LCD.h"

//ALL these related with display
extern uint8_t SmallFont[]; 
extern uint8_t BigFont[];

BusOut myBusOut(PB_0,PB_1,PB_2,PB_3,PB_4,PB_5,PB_6,PB_7,PB_8,PB_9,PB_10,PB_11,PB_12,PB_13,PB_14,PB_15);
TFT_LCD  myScreen(ILI9325C,PC_7,PC_1, PC_6, PC_0,&myBusOut);

//end of display

/* The Pins for the Stepping Motor are:
*
*    A  -> PA_9
*   ~A  -> PA_10
*    B  -> PA_11
*   ~B  -> PA_12
*/
#define MASK (0x1E00) // the pins above defined
PortOut stepMotor(PortA,MASK);

Ticker step_ticker;


uint16_t sequence[8]={0x0200,0x0A00,0x0800,0x0C00,0x0400,0x1400,0x1000,0x1200};
uint8_t seq_i=0;

#define WAVE_INC 2
uint8_t seq_increment=WAVE_INC;

int n_steps;
int direction;

bool moving=false;

void step_motor() {
 // static int n=0;
  
  stepMotor=sequence[seq_i];
  
  seq_i+=(seq_increment*direction);
  seq_i&=0x07;

  // myScreen.printNumI(n_steps, LEFT, 70, 10, ' ');

    if(--n_steps<=0){  n_steps=0;
                    moving =false;
                      step_ticker.detach();      
                      
                       }        
}

void wave_drive(int dir, int ns)
{
  direction=dir;
  n_steps=ns;
  step_ticker.attach(&step_motor,0.050);  //toggle at 50ms
  moving=true;
}

int main() {
//display 
   wait(3);
  myScreen.InitLCD();
  myScreen.setBackColor(BLACK);
  myScreen.setColor(BLACK);
  myScreen.clrScr();   
 
  myScreen.setColor(GREEN);
  myScreen.setFont(SmallFont);

  myScreen.print("Stepper Motor Program",LEFT, 10);
//display

 
    while (true) {
     
     myScreen.print("Wave Drive  ->>      ", LEFT, 50);
     wave_drive(1,200);
//     while(n_steps>0){
       while(moving){
            myScreen.printNumI(n_steps, LEFT, 90, 10, ' ');//<-----HERE IT WORKS
            }  // stop while moving

     myScreen.print("Wave Drive  <<-      ", LEFT, 50);
     wave_drive(-1,200);
//     while(n_steps>0){
      while(moving){
           // myScreen.printNumI(n_steps, LEFT, 90, 10, ' ');  //strange it does not work when commented in
               ;
            }   // stop while moving
     
         

    }//while true
}



As you can see I put a "while(moving)" clause to wait for the ticker to be detached. but it waits for ever!!! (except when I put a totally unrelated instruction there....

that does not make sense. How can I know that a process has been detached???

Thank you for any help you can give me

Question relating to:

2 Answers

8 years, 1 month ago.

The compiler may do some unexpected optimisations when you use a variable (moving) in your while loop that is modified in an interrupt. Try

volatile bool moving=false;

The attach/detach may also be tricky and cause timing issues when the ticker is running at a relatively high rate. You may simply keep the ticker and the attached call to step_motor() going and add a test on the 'moving' variable inside the step_motor() function to decide whether or not a next step is needed.

Thank you very much. It worked :) And I remembered an old lesson on embedded programming I had forgotten :)

posted by Cristian Fuentes 14 Mar 2016
8 years, 1 month ago.

Start by defining moving as 'volatile', so volatile bool moving = false;. The problem is (well there could also be other issues) that the compiler does not realise moving can be changed in the interrupt. So it optimizes your while loop to check a copy of 'moving' in its register, while the interrupt will change it in the SRAM. Normally when something has been changed, the compiler will make sure it retrieves latest version of this variable, but the compiler does not realise it can be changed.

Adding volatile forces it to always retrieve the data from the SRAM.

Thank you very much. As I commented previously it worked! I got reminded of an old lesson of embedded programming I had forgotten. Wish I could mark thanks to both of you (I can't :( ) Your help is greatly appreciated

posted by Cristian Fuentes 14 Mar 2016