4年工学基礎研究(前期)で作成したペンプロッタの制御プログラム

Dependencies:   SPM_simple mbed trapezoidalMotionCal

main.cpp

Committer:
Akito914
Date:
2018-05-28
Revision:
6:0a3c58539a2a
Parent:
5:0abb848bb2f9

File content as of revision 6:0a3c58539a2a:

#include "mbed.h"
#include "SPM.h"
#include "trapezoidalMotionCal.h"

#define PEN_SAVEMODE    120
#define PEN_UP          90
#define PEN_DOWN        70

#define RTO_SPEED       500

//stepMotor x_axis(PC_4 ,PB_13 ,PB_14 ,PB_15);
stepMotor x_axis(PB_15 ,PB_14 ,PB_13 ,PC_4);
//stepMotor y_axis(PB_1  ,PB_2  ,PB_12 ,PA_11);
stepMotor y_axis(PA_11  ,PB_12  ,PB_2 ,PB_1);

trapezoidalMotionCal motionCal(50, 500, 4000, 10000, -10000);

PwmOut servo(PC_6);
PwmOut speaker(/*PC_8*/PA_15);

DigitalIn x_originSW(PA_0);
DigitalIn y_originSW(PA_1);

DigitalOut myled(LED1);
Serial pc(USBTX,USBRX);
Serial debugPort(PA_9,PA_10);

typedef struct {
    int32_t x;
    int32_t y;
} coordinate_t;

int job = 0;
int nextMode = 0;
int penMotion = 0; // 0: up 1: down
coordinate_t nextPosition = {0};

coordinate_t currentPosition = {0};

void pcIntr();
void rcdataProcessing(int32_t *RXData);
void sendRequest();

void driveServo(int deg);
void linearInterpolation(coordinate_t cStart, coordinate_t cTarg);
void trapezoid(int32_t targSteps);

void beep(int T_us,int t_ms);
void pi(int times);
void q_sound(void);
void ans_sound(void);
void piroro(void);

// 受信割込みハンドラ
void pcIntr()
{
    static int32_t RXByte[8] = {0};
    static int32_t RXCount   = 0;
    
    char temp = pc.getc();
    
    if(temp == 0xEA)exit(-1);
    
    if(((temp >> 5) & 0x07) != RXCount){
        RXCount = 0;
    }
    else{
        RXByte[RXCount] = temp;
        
        if(RXCount < 7){
            RXCount += 1;
        }
        else{ // all data received
            RXCount = 0;
            rcdataProcessing(RXByte);
        }
    }
}


void rcdataProcessing(int32_t *RXData){
    
    if((RXData[0] & 0x08) != 0){ // move mode
        nextPosition.x = (RXData[1] & 0x0f) | ((RXData[2] & 0x0f) << 4) | ((RXData[3] & 0x0f) << 8);
        nextPosition.y = (RXData[4] & 0x0f) | ((RXData[5] & 0x0f) << 4) | ((RXData[6] & 0x0f) << 8);
        nextMode = 1;
    }
    else{ // pen mode
        nextMode = 0;
        penMotion = RXData[0] & 0x01;
    }
    job = 1;
}

void return2origin(){
    int32_t RTO_stepPeriod = 1000000 / RTO_SPEED;
    
    while((x_originSW.read() == 0)||(y_originSW.read() == 0)){
        wait_us(RTO_stepPeriod);
        if(x_originSW.read() == 0)x_axis.oneStep(false);
        if(y_originSW.read() == 0)y_axis.oneStep(false);
    }
    
}

void sendRequest(){
    pc.putc(0x01);
}

void driveServo(int deg){
    const static int servo_offset   =830;
    const static float servo_gain   =10.0;
    
    deg=deg*servo_gain+servo_offset;
    servo.pulsewidth_us(deg);
    
    return;
}

int main()
{
    coordinate_t runningPosition = {0};
    int runningPenMotion = 0;
    
    pc.baud(115200);
    debugPort.baud(115200);
    
    pc.attach(pcIntr, Serial::RxIrq);
    
    wait_ms(100);
    
    debugPort.printf("Hello Debug Port\r\n");
    
    x_axis.lock();
    y_axis.lock();
    
    driveServo(PEN_UP);
    
    wait_ms(500);
    
    return2origin();
    
    sendRequest();
    
    while(1) {
        
        while(job == 0);
        
        if(nextMode != 0){ // move mode
            runningPosition = nextPosition;
            job = 0;
            sendRequest();
            linearInterpolation(currentPosition, runningPosition);
            currentPosition = runningPosition;
            wait_ms(10);
            debugPort.printf("moved [%d,%d]\r\n", runningPosition.x, runningPosition.y);
        }
        else{ // pen mode
            runningPenMotion = penMotion;
            job = 0;
            sendRequest();
            if(runningPenMotion != 0){
                driveServo(PEN_DOWN);
                wait_ms(100);
                debugPort.printf("pen down\r\n");
            }
            else{
                driveServo(PEN_UP);
                wait_ms(100);
                debugPort.printf("pen up\r\n");
            }
        }
    }
}

void linearInterpolation(coordinate_t cStart, coordinate_t cTarg)
{
    coordinate_t delta;
    int32_t error = 0;
    bool x_inv = false;
    bool y_inv = false;
    coordinate_t cCurrent = {cStart.x, cStart.y};
    coordinate_t inc = {0, 0};
    uint32_t period_us = 0;
    
    if(cStart.x > cTarg.x) {
        x_inv = true;
        cTarg.x = cStart.x * 2 - cTarg.x;
    }
    if(cStart.y > cTarg.y) {
        y_inv = true;
        cTarg.y = cStart.y * 2 - cTarg.y;
    }
    
    delta.x = cTarg.x - cStart.x;
    delta.y = cTarg.y - cStart.y;
    
    if((delta.x == 0)&&(delta.y == 0)){
        return;
    }
    
    if(delta.x < delta.y){
        motionCal.setTarg(delta.y);
    }
    else{
        motionCal.setTarg(delta.x);
    }
    
    while(true) {
        inc.x = 0;
        inc.y = 0;
        if(delta.x == 0){
            if(cCurrent.y < cTarg.y){
                cCurrent.y++;
                inc.y = 1;
            }
            else{
                break;
            }
            period_us = motionCal.calStepDelay(cCurrent.y - cStart.y);
        }
        else if(delta.y == 0){
            if(cCurrent.x < cTarg.x){
                cCurrent.x++;
                inc.x = 1;
            }
            else{
                break;
            }
            period_us = motionCal.calStepDelay(cCurrent.x - cStart.x);
        }
        else if(delta.y > delta.x) {
            if(cCurrent.y < cTarg.y){
                cCurrent.y++;
                inc.y = 1;
            }
            else{
                break;
            }
            error += delta.x;
            if(error >= delta.y) {
                error -= delta.y;
                cCurrent.x++;
                inc.x = 1;
            }
            period_us = motionCal.calStepDelay(cCurrent.y - cStart.y);
        } else {
            if(cCurrent.x < cTarg.x){
                cCurrent.x++;
                inc.x = 1;
            }
            else{
                break;
            }
            error += delta.y;
            if(error >= delta.x) {
                error -= delta.x;
                cCurrent.y++;
                inc.y = 1;
            }
            period_us = motionCal.calStepDelay(cCurrent.x - cStart.x);
        }
        
        if(inc.x != 0)x_axis.oneStep(x_inv == 0);
        if(inc.y != 0)y_axis.oneStep(y_inv == 0);
        
        wait_us(period_us);
        
    }
}

void beep(int T_us,int t_ms){
    
    if(T_us==0 || t_ms==0)return;
    
    speaker.period_us(T_us);
    speaker.write(0.10);
    
    wait_ms(t_ms);
    
    speaker.write(0.0);
    speaker.period_us(100);
    
    return;
}

void pi(int times){
    int count=0;
    
    for(count=0;count<times;count++){
        beep(379,50);
        wait_ms(50);
    }
    wait_ms(300);
}

void q_sound(void){
    beep(478,100);
    beep(379,100);
}

void ans_sound(void){
    beep(379,100);
    beep(478,100);
}

void piroro(void){
    beep(379,100);
    beep(426,100);
    beep(478,100);
}