2016-10-10 115 views
0

我目前在我的Arduino运行此程序..为什么arduino忽略函数调用?

main.ino

#include "speed_profile.h" 


void setup() { 
    // put your setup code here, to run once: 
    output_pin_setup(); 
    cli(); 
    timer1_setup(); 
    sei(); 
} 

void loop() 
{ 
     //int motor_steps = 23400;//-9600; //23400 - 100% 
     // Accelration to use. 
     //int motor_acceleration = 500;//500; 
     // Deceleration to use. 
     //int motor_deceleration = 500;//500; 
     // Speed to use. 
     //int motor_speed = 1000; // 1000 
     init_tipper_position(); 
     compute_speed_profile(23400, 500, 500, 1000); 
} 

,由于某种原因没有执行init_tipper_position,它看起来像这样。

void init_tipper_position() 
{ 
    digitalWrite(en_pin, HIGH); 
    delay(1); 

    digitalWrite(dir_pin, LOW); 
    delay(1); 


    while((PINB & (0 << 2))) 
    { 
    digitalWrite(step_pin, HIGH); 
    delayMicroseconds(100); 
    digitalWrite(step_pin, LOW); 
    delayMicroseconds(100); 

    } 

    digitalWrite(en_pin, LOW); 

} 

我知道,由于以下原因,它肯定会跳过。

  1. 1)我正在使用的硬件上没有任何反应。它假设到 移动一个移动,直到一个传感器被激活,但没有发生。

  2. 如果使能引脚为高,这将是不可能的移动马达, 其中有可能在这种情况下

  3. 我有一个逻辑分析仪,其, 我可以范围与输出,这表明启用不高。

那么为什么程序跳过这部分功能。 应该注意的是,如果我从main删除函数,该函数将起作用。

代码中使用的所有函数都可以在.cpp文件中看到。 profile只是一个跟踪一些变量的结构。

的.cpp

#include "speed_profile.h" 


volatile speed_profile profile; 

ros::NodeHandle_<ArduinoHardware, 1, 2, 125, 125> nh; 
//ros::NodeHandle nh; 

std_msgs::Int8 status_step_count; 
std_msgs::Int8 status_tipper_availability; 
ros::Publisher chatter_status("tipper_status", &status_step_count); 
ros::Publisher chatter_availabilty("tipper_availability", &status_tipper_availability); 

volatile bool global_state = false; 
int received_data = 0; 


void call_back_control(const std_msgs::Empty & msg) 
{ 
    global_state = true; 

    received_data = (10 *23400.0)/100.0; // Converts input to motor_steps. 
} 

ros::Subscriber<std_msgs::Empty> sub_control("tipper_control", &call_back_control); 

void output_pin_setup() 
{ 
    pinMode(en_pin, OUTPUT); 
    pinMode(dir_pin, OUTPUT); 
    pinMode(step_pin, OUTPUT); 
    pinMode(slot_sensor_pin,INPUT_PULLUP); 
    nh.initNode(); 
    nh.advertise(chatter_status); 
    nh.advertise(chatter_availabilty); 
    nh.subscribe(sub_control); 
    //nh.subscribe(sub_command); 
    profile.current_step_position = 0; 
    delay(10); 
    nh.getHardware()->setBaud(57600); 
} 

void init_tipper_position() 
{ 
    digitalWrite(en_pin, HIGH); 
    delay(1); 

    digitalWrite(dir_pin, LOW); 
    delay(1); 


    while((PINB & (0 << 2))) 
    { 
    digitalWrite(step_pin, HIGH); 
    delayMicroseconds(100); 
    digitalWrite(step_pin, LOW); 
    delayMicroseconds(100); 

    } 

    digitalWrite(en_pin, LOW); 

} 
void timer1_setup() 
{ 
    // Tells what part of speed ramp we are in. 
    profile.run_state = STOP; 

    // Timer/Counter 1 in mode 4 CTC (Not running). 
    TCCR1B = (1 << WGM12); 

    // Timer/Counter 1 Output Compare A Match Interrupt enable. 
    TIMSK1 = (1 << OCIE1A); 
} 

void compute_speed_profile(signed int motor_steps, unsigned int motor_accel, unsigned int motor_decel, unsigned int motor_speed) 
{ 
    while (global_state == false) 
    { 
    //do nothing 
    status_step_count.data = ((float)(profile.current_step_position/23400.0)) * 100.0; //map(profile.current_step_position,0,23400,0,100); // could be expensive -- Nice flowing is only available with float 
    status_tipper_availability.data = 1; 

    chatter_status.publish(&status_step_count); 
    chatter_availabilty.publish(&status_tipper_availability); 
    nh.spinOnce(); 
    } 

    digitalWrite(en_pin, HIGH); 
    delay(1); 

    signed int move_steps; 

    if(received_data > profile.current_step_position) // Compares whether received percentage (converted to motor_steps) is greater or smaller than current_step_position. 
    { 
    profile.dir = CCW; 
    //motor_steps = -motor_steps; 
    move_steps = profile.current_step_position - received_data; 
    digitalWrite(dir_pin, HIGH);       
    } 
    else 
    { 
    profile.dir = CW; 
    move_steps = profile.current_step_position - received_data; 
    digitalWrite(dir_pin, LOW); 
    } 

    delay(1); 


    computation_of_speed_profile(move_steps, motor_accel, motor_decel, motor_speed); // Computes constants for profile.. 

    OCR1A = 10; 
    // Set Timer/Counter to divide clock by 8 
    TCCR1B |= ((0 << CS12) | (1 << CS11) | (0 << CS10)); 


    while (global_state == true) 
    { 
    status_step_count.data = ((float)(profile.current_step_position/23400.0)) * 100.0; //map(profile.current_step_position,0,23400,0,100); 
    status_tipper_availability.data = 0; 

    chatter_availabilty.publish(&status_tipper_availability); 
    chatter_status.publish(&status_step_count); 
    nh.spinOnce(); 
    //delay(100); 
    } 
} 

ISR(TIMER1_COMPA_vect) 
{ 
    // Holds next delay period. 
    unsigned int new_first_step_delay; 

    // Remember the last step delay used when accelrating. 
    static int last_accel_delay; 

    // Counting steps when moving. 
    static unsigned int step_count = 0; 

    // Keep track of remainder from new_step-delay calculation to incrase accurancy 
    static unsigned int rest = 0; 
    OCR1A = profile.first_step_delay; 
    switch (profile.run_state) 
    { 

    case STOP: 
     step_count = 0; 
     global_state = false; 
     rest = 0; 
     TCCR1B &= ~((1 << CS12) | (1 << CS11) | (1 << CS10)); // Stop the timer, No clock source 
     break; 

    case ACCEL: 
     PORTB ^= _BV(PB3); // Toggles the step_pin 
     step_count++; 

     if (profile.dir == CCW) 
     { 
     profile.current_step_position++; 
     } 
     else 
     { 
     profile.current_step_position--; 
     } 

     profile.accel_count++; 
     new_first_step_delay = profile.first_step_delay - (((2 * (long)profile.first_step_delay) + rest)/(4 * profile.accel_count + 1)); 
     rest = ((2 * (long)profile.first_step_delay) + rest) % (4 * profile.accel_count + 1); 

     // Chech if we should start decelration. 
     if (step_count >= profile.decel_start) 
     { 
     profile.accel_count = profile.decel_length; 
     profile.run_state = DECEL; 
     } 

     // Chech if we hitted max speed. 
     else if (new_first_step_delay <= profile.min_time_delay) 
     { 
     last_accel_delay = new_first_step_delay; 
     new_first_step_delay = profile.min_time_delay; 
     rest = 0; 
     profile.run_state = RUN; 
     } 
     break; 
    case RUN: 
     PORTB ^= _BV(PB3); // Toggles the step_pin 
     step_count++; 

     if (profile.dir == CCW) 
     { 
     profile.current_step_position++; 
     } 
     else 
     { 
     profile.current_step_position--; 
     } 
     new_first_step_delay = profile.min_time_delay; 
     // Chech if we should start decelration. 
     if (step_count >= profile.decel_start) 
     { 
     profile.accel_count = profile.decel_length; 
     // Start decelration with same delay as accel ended with. 
     new_first_step_delay = last_accel_delay; 
     profile.run_state = DECEL; 
     } 
     break; 
    case DECEL: 
     PORTB ^= _BV(PB3); // Toggles the step_pin 
     step_count++; 
     if (profile.dir == CCW) 
     { 
     profile.current_step_position++; 
     } 
     else 
     { 
     profile.current_step_position--; 
     } 
     profile.accel_count++; 
     new_first_step_delay = profile.first_step_delay - (((2 * (long)profile.first_step_delay) + rest)/(4 * profile.accel_count + 1)); 
     rest = ((2 * (long)profile.first_step_delay) + rest) % (4 * profile.accel_count + 1); 
     // Check if we at last step 

     if (profile.accel_count >= 0) 
     { 
     digitalWrite(en_pin, !digitalRead(en_pin)); 
     profile.run_state = STOP; 
     } 
     break; 

    } 

    profile.first_step_delay = new_first_step_delay; 

} 

.h文件中

/* 
* Contains the class concerning with calculating the proper speed profile 
* for accelerating and decelerating the stepper motor. 
* 
*/ 

#ifndef speed_profile_h 
#define speed_profile_h 


#include <Arduino.h> 
#include <ros.h> 
#include <std_msgs/Int8.h> 
#include <std_msgs/Empty.h> 

// Timer/Counter 1 running on 3,686MHz/8 = 460,75kHz (2,17uS). (T1-FREQ 460750) 
//#define T1_FREQ 460750 
#define T1_FREQ 1382400 

//! Number of (full)steps per round on stepper motor in use. 
#define FSPR 1600 

// Maths constants. To simplify maths when calculating in compute_speed_profile(). 
#define ALPHA (2*3.14159/FSPR)     // 2*pi/spr 
#define A_T_x100 ((long)(ALPHA*T1_FREQ*100))  // (ALPHA/T1_FREQ)*100 
#define T1_FREQ_148 ((int)((T1_FREQ*0.676)/100)) // divided by 100 and scaled by 0.676 
#define A_SQ (long)(ALPHA*2*10000000000)   // ALPHA*2*10000000000 
#define A_x20000 (int)(ALPHA*20000)    // ALPHA*20000 

// Speed ramp states 
#define STOP 0 
#define ACCEL 1 
#define DECEL 2 
#define RUN 3 

// Pin numbering 
#define en_pin 13 
#define dir_pin 12 
#define step_pin 11 
#define slot_sensor_pin 10 

// Motor direction 
#define CW 0 
#define CCW 1 

typedef struct 
{ 
    unsigned char run_state : 3; // Determining the state of the speed profile 
    unsigned char dir: 1; // Determining the direction the motor has to move - Start being CCW 
    unsigned int first_step_delay; // Period time for the next timer_delay, determines the acceleration rate. 
    unsigned int decel_start; // Determines at which step the deceleration should begin. 
    signed int decel_length; // Set the deceleration length 
    signed int min_time_delay; //minium time required time_delay for achieving the wanted speed. 
    signed int accel_count; // counter used when computing step_delay for acceleration/decelleration. 
    volatile signed int current_step_position; // contains the current step_position 

}speed_profile; 


void compute_speed_profile(signed int motor_steps, unsigned int motor_accel, unsigned int motor_decel, unsigned int motor_speed); 
void computation_of_speed_profile(signed int motor_steps, unsigned int motor_accel, unsigned int motor_decel, unsigned int motor_speed); 
void init_tipper_position(); 
void timer1_setup(void); 
void output_pin_setup(void); 
#endif 
+3

解决此类问题的正确工具是您的调试器。在*堆栈溢出问题之前,您应该逐行执行您的代码。如需更多帮助,请阅读[如何调试小程序(由Eric Lippert撰写)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。至少,您应该\编辑您的问题,以包含一个[最小,完整和可验证](http://stackoverflow.com/help/mcve)示例,该示例再现了您的问题,以及您在调试器。 –

回答

3
while((PINB & (0 << 2))) 

这是不正确的。 0移动任何数量总是零。任何与零相连的东西总是为零,这就是false,所以循环从不输入。

+0

它假设读取int循环中的sensor_value。即使将其更改为1,它也不起作用。 –

+0

但感谢您浏览代码:) –

相关问题