Artem Solomatin
/
pendudu
fsdfds
main.cpp
- Committer:
- teamat
- Date:
- 2020-05-17
- Revision:
- 5:9aae12408a54
- Parent:
- 4:fd49edfabfb2
- Child:
- 6:999e8ae7d969
File content as of revision 5:9aae12408a54:
#include "mbed.h" #define M_PI 3.14159265358979323846f #define smoothingNumber 6 #define STATE_ERROR 0 #define STATE_INIT 1 #define STATE_GOTO_START 2 #define STATE_GOTO_END_COUNTING 3 #define STATE_GOTO_MIDDLE 4 #define STATE_WAITING 5 #define STATE_GOTO_SWING 6 #define STATE_START_SWING 7 #define STATE_SWING_RIGHT 8 #define STATE_SWING_LEFT 9 #define STATE_EMPTY_SWING 10 #define DIR_LEFT 0 #define DIR_RIGHT 1 //Serial pc(D1,D0,4800); DigitalOut RCout(D10); DigitalOut dir(D9); InterruptIn leftSwitch(D2); InterruptIn rightSwitch(D3); Ticker tick; Ticker speedTicker; Ticker swingTicker; DigitalOut myled(LED2); RawSerial rpc(D1,D0,9600); int period_us = 26;//300 26 long pos=0; long railLength = 0; uint8_t state=STATE_INIT; Timer t; SPI spi(D11,D12,D13);// mosi, miso, sclk DigitalOut cs(D5); float radius = 0.0025; float angularPosNew = 0; float angularPosOld = 0; float timeOld = 0.0f; float timeStart = 0.0f; float dx = 0; float xPosNew = 0; float xPosOld = 0; float speed = 0; double dAngle = 0.0f; double anSpd = 0.0f; float timeOldPos = 0.0f; float timeStartPos = 0.0f; float angle=0.0f; float angleOffset = 0; float control = 0.0f; double PIPI = 6.28; bool canSend = false; typedef union { float number[6]; uint8_t numberCh[24]; } my_union; my_union myUnion; bool isPendulumSwinging() { return state == STATE_SWING_RIGHT || state == STATE_SWING_LEFT; } float getPosMM() { //return (pos-railLength/2) * 550.0f/railLength; //return (pos - railLength / 2) * (350.0f / railLength); return pos / 3500.0f; } uint16_t getPendulumPos(){ cs=0; wait_ms(1); uint16_t d=spi.write((short)0x00); d=d<<1;//fucking shithole fakebit d=d>>6;//no need debug info cs=1; wait_ms(1); return (uint16_t)d; } float getPendulumAngle(){ angle = getPendulumPos(); angle = angle * 6.28f / 1024.0f; angle += angleOffset; if (angle > PIPI + 0.01) { angle = fmod((angle + 3.14), PIPI) - 3.14; if (angle < -3.14) { angle += PIPI; } } return angle; } /* ANGULAR SPEED CALC */ void getDeltaAng(){ angularPosNew = getPendulumAngle(); dAngle = fmod((angularPosNew - angularPosOld + 3.14), PIPI) - 3.14; if (dAngle < -3.14) { dAngle += PIPI; } angularPosOld = angularPosNew; } void getAngularSpeed(){ float deltaTime; timeStart = float(t.read()); deltaTime = (timeStart - timeOld); getDeltaAng(); anSpd = dAngle / deltaTime; timeOld=timeStart; //взятие по модулю, спросить } /* SPEED CALC */ void getDeltaPos() { float delta = 0; xPosNew = getPosMM(); delta = xPosNew - xPosOld; dx = delta; xPosOld = xPosNew; } /*float getSpeed(){ float deltaTime; float speed; getDeltaPos(); timeStartPos = float(t.read()); deltaTime = (timeStartPos - timeOldPos); speed = (dx) * deltaTime; timeOldPos = timeStartPos; //взятие по модулю, спросить return speed; }*/ void calcSpeed() { xPosNew = getPosMM() / 1000; speed = xPosNew - xPosOld; xPosOld = xPosNew; } void calcControl() { float frequency = 1000000 / (period_us / 2); float rates = frequency / 6400; control = rates * PIPI * radius; } void stepperFlip() { if (state != STATE_WAITING && state != STATE_ERROR && state != STATE_INIT && state){ RCout = !RCout; pos += (dir.read() * 2 - 1); } if (state == STATE_GOTO_MIDDLE && pos == railLength / 2) { state = STATE_WAITING; } if (state == STATE_SWING_LEFT && state==STATE_SWING_RIGHT) { pos += (dir.read() * 2 - 1); RCout = !RCout; } } void updatePeriod(){ tick.detach(); tick.attach_us (&stepperFlip, period_us / 2.0f); } void leftEnd() { dir = DIR_RIGHT; if (state == STATE_GOTO_START) { state = STATE_GOTO_END_COUNTING; pos = 0; } else if (isPendulumSwinging()) { state = STATE_GOTO_MIDDLE; //angleOffset -= 0.006191; //state = STATE_ERROR; } //при втыкании в концевик меняем смещение (offset) } void rightEnd() { dir=DIR_LEFT; if (state == STATE_GOTO_END_COUNTING) { railLength=pos; state = STATE_GOTO_MIDDLE; } else if (isPendulumSwinging()) { state = STATE_GOTO_MIDDLE; //angleOffset += 0.006191; //state = STATE_ERROR; } } void getSwingDirectory() { control = -control; if (dir == DIR_RIGHT) { state = STATE_SWING_RIGHT; dir = DIR_LEFT; return; } if (dir == DIR_LEFT) { state = STATE_SWING_LEFT; dir = DIR_RIGHT; return; } } void sendData() { myUnion.number[0] = t.read(); myUnion.number[1] = dx; myUnion.number[2] = speed; //myUnion.number[3] = dAngle; myUnion.number[3] = angle; myUnion.number[4] = anSpd; myUnion.number[5] = control; for(int i = 0; i < 24; i++) { rpc.putc(myUnion.numberCh[i]); } } void Rx_interrupt() { int command = rpc.getc(); if (command == 50) { canSend = true; } return; } int main() { RCout = 1; wait_ms(500); spi.format(16,2); spi.frequency(1000000); t.start(); leftSwitch.rise(&leftEnd); rightSwitch.rise(&rightEnd); calcControl(); rpc.attach(&Rx_interrupt, Serial::RxIrq); for (int i=5; i>0; i--) { getPendulumAngle(); wait_ms(500); } angleOffset= 3.14 - angle; updatePeriod(); state=STATE_GOTO_START; dir=DIR_LEFT; while(1) { getAngularSpeed(); if(canSend) { sendData(); } switch(state) { case STATE_WAITING: state = STATE_GOTO_SWING; break; case STATE_GOTO_START: break; case STATE_GOTO_END_COUNTING: break; case STATE_GOTO_SWING: speedTicker.attach(calcSpeed, 1); swingTicker.attach(getSwingDirectory, 1); state = STATE_SWING_LEFT; break; case STATE_SWING_LEFT: break; case STATE_SWING_RIGHT: break; default: break; } //wait_ms(5); } }