Myself / Mbed 2 deprecated testing_servo_control

Dependencies:   mbed

main.cpp

Committer:
wcyam2
Date:
2020-07-05
Revision:
0:022cc499efd8

File content as of revision 0:022cc499efd8:

/*  
########    Project name:       servo_control
#readme#    Program creater:    Chong
########    Last edit:          19/6/2020

[aims]
    This program is to test the drive the servo from middle position.

[board]
    NUCLEO-F401RE
    F446RE_Universal_board with button
        Creater:    Big Vic
        Date:       29/4/2020
[input] button design
    A5    A4      A3      A2      A1      A0
    start read    +1      reset   -1      read

    #after start
    A5    A4      A3      A2      A1      A0
    prev  max     +%      mid     -%      min

[output]
    D3
    pwm

[flow]
    initialize:
    blink onboard led 2 second
    servo position = middle position
    
    main:
    change postition depend on the button pressed
    # only button [+5%(A3)] and [-5%(A1)] will change the position after release the button
    # other button will change the position immediately

[user guide]
    goto user setting
    check the period / hertz of the servo               e.g. 0.020f
    check the minimum and maximum valid pulsewidth      e.g. 500, 2500
    check the minimum and maximum valid degree [0,360]  e.g. 0, 180
    
    
*/
#include "mbed.h"
#define isOn(a) a<0.3f  //Analog button pressed
AnalogIn min_post(A0);
AnalogIn minus_post(A1);
AnalogIn mid_post(A2);
AnalogIn plus_post(A3);
AnalogIn max_post(A4);
AnalogIn prev_post(A5);
InterruptIn mybutton(BUTTON1);
//servo output
PwmOut servo(D3);

//debug light
DigitalOut led(PA_5);

//user setting 
    //hertz(hz) / period time(s) of servo
    const double hertz = 50;
    const double servo_period = 1/hertz;
    //pulsewidth(us)
    const double min_us = 500;
    const double max_us = 2500;
    //degree
    const double min_degree = 0;            //refer to the minimum pulsewidth(us)
    const double max_degree = 180;          //refer to the maximum pulsewidth(us)
    
    //mode
    const bool degree_mode = false;             //  0: false, 1:true
    
    //button setting for [+10%(A3)] and [-10%(A1)]
        //change if degree_mode == true
        const double change_degree = 1;         //range (0.0, 180.0]
        //change if degree_mode == false
        const double change_percentage = 0.05;   //range (0.0, 1.0)
        
//user setting end

//------------------------------------------------------------------------------------------------------------
            
//calculate variable
    const double mid_us = (max_us + min_us)/2;
    const double change = degree_mode?change_degree/(max_degree - min_degree)*(max_us - min_us)+ min_us:(max_us - min_us)*change_percentage;
    int factor = 2;
    bool reset = true;
//calculate variable end
    
// degree to pwm function
double degree2pwm(double d){
    return (d/(max_degree - min_degree)*(max_us - min_us)+ min_us);
}

//initialize function 
void blink_testing(double w){
    led = 0;
    for(int i = 1; i <= factor; i++){
        led = 1; wait(w);
        led = 0; wait(w);
    }
}

void m(){
//    [input] button design
//    #after start
//    A5    A4      A3      A2      A1      A0
//    prev  max     +%      mid     -%      min
    //set previous, current and next pulsewidth status
    double prev_pulsewidth = mid_us;
    double curr_pulsewidth = mid_us;
    double next_pulsewidth = mid_us;
    while(reset){
        //button control (change: next_pulsewidth)
        if      (isOn(mid_post))      next_pulsewidth = mid_us;
        else if (isOn(min_post))      next_pulsewidth = min_us;
        else if (isOn(max_post))      next_pulsewidth = max_us;
        
        else if (isOn(minus_post)){
            //wait until release button
            while(isOn(minus_post));    next_pulsewidth = max(min_us, next_pulsewidth - change*factor);
        }
        else if (isOn(plus_post)){
            //wait until release button
            while(isOn(plus_post));     next_pulsewidth = min(max_us, next_pulsewidth + change*factor);
        }
        else if (isOn(prev_post)){
            //action immediately
            servo.pulsewidth_us(prev_pulsewidth);
            next_pulsewidth = prev_pulsewidth;
            //wait until release button
            while(isOn(plus_post));
        }
        //button control end
        
        //action if button change exclude [prev_post(A5)]
        if (next_pulsewidth != curr_pulsewidth){
            servo.pulsewidth_us(next_pulsewidth);
            prev_pulsewidth = curr_pulsewidth;
            curr_pulsewidth = next_pulsewidth;
            led = !led;
            //wait(0.2f);
        }
    }
}
void restart(){
    reset = false;
    led = 0; wait (0.2f);
    blink_testing(0.2f);
}
int main() {
    //initialize
    mybutton.rise(&restart);
    blink_testing(0.5f);                    //blink onboard led 2 second
    servo.period(servo_period);             //set period time of servo
    servo.pulsewidth_us(mid_us);            //write the pulsewidth (init: mid)
    factor = 1;
    while(1){
//        [input] button design
//        A5    A4      A3      A2      A1      A0
//        start read    +1      reset   -1      read
        if      (isOn(mid_post))        factor = 1;
        else if (isOn(minus_post)){
            //wait until release button
            while(isOn(minus_post));    factor = max(1, factor-1);
        }
        else if (isOn(plus_post)){
            //wait until release button
            while(isOn(plus_post));     factor = min(10, factor+1);
        }   
        else if (isOn(max_post) || isOn(min_post)){
            //wait until release button
            while(isOn(max_post) || isOn(min_post));
            blink_testing(0.2f);
        }
        else if (isOn(prev_post)){
            //wait until release button
            while(isOn(plus_post));       m();        //start
        }
        reset = true;

    }
    
}