Diagonaal berekenen lukt, meerdere outputs nog niet
Dependencies: mbed FastPWM HIDScope MODSERIAL QEI
Diff: main.cpp
- Revision:
- 6:ee243782bf51
- Parent:
- 5:a9da7bc89b24
--- a/main.cpp Mon Oct 17 14:25:12 2016 +0000 +++ b/main.cpp Thu Oct 20 12:07:30 2016 +0000 @@ -1,230 +1,315 @@ #include "mbed.h" -#include "math.h" -#include "iostream" +#include "FastPWM.h" +#include "HIDScope.h" +#include "QEI.h" +#include "MODSERIAL.h" #define SERIAL_BAUD 115200 - -Serial pc(USBTX,USBRX); -InterruptIn Button1(PTC6); // DIT WORDT EEN ANDERE BUTTON - -// tickers -Ticker TickerCaseBepalen; -Ticker TickerVeranderenXY; -Ticker TickerAfstandBerekenen; -Ticker TickerMotorHoekBerekenen; -Ticker TickerBerekenenBewegingsHoek; -Ticker TickerFlipperBewegen; - -// in te voeren x en y waardes -volatile float x = 0.0; -volatile float y = 305.5; -volatile float vorigex = 0.0; -volatile float vorigey = 0.0; + +MODSERIAL pc(USBTX,USBRX); +// Set button pins +InterruptIn button1(PTB9); +InterruptIn button2(PTA1); -// waardes -volatile const float a = 50.0; // de afstand van gekozen assenstelsel tot de armas (assenstelsel precies in het midden) KEERTJE NAMETEN -volatile const float Bar = 200.0; // lengte van de armen KEERTJE NAMETEN -volatile const float pi = 3.14159265359; -volatile float VorigeHoek1 = 1.0/3.0*pi; // begin hoek van 90 graden -volatile float VorigeHoek2 = 1.0/3.0*pi; -volatile float Step = 1; // EEN GOK VOOR HET STAPJE EN MOET DUS NOG AANGEPAST -volatile float MaxHoek = pi - 30*pi/180; // de hoek voordat arm het opstakel raakt (max hoek is 24.9 tussen arm en opstakel) +// Set AnalogIn potmeters +AnalogIn pot1(A3); +AnalogIn pot2(A4); -volatile float Dia1 = 0.0; -volatile float Dia2 = 0.0; -volatile float MotorHoek1 = 0.0; -volatile float MotorHoek2 = 0.0; -volatile float BewegingsHoek1 = 0.0; -volatile float BewegingsHoek2 = 0.0; -volatile bool Richting1 = true; // cw = true, ccw = false -volatile bool Richting2 = true; -volatile bool FlipperAan = false; // als true dan flipper aanzetten -bool BezigMetCalibreren = true; // we beginnen met calibreren -bool BeginnenMetFlippen = false; // om de flipper aan te zetten -bool BezigMetFlippen = false; // om verandering in x en y tegen te houden tijdens het flippen. DIT WORDT VERANDERD IN SJOERDS DEEL (NAAM CONTROLEREN) +// Set motor Pinouts +DigitalOut motor1_dir(D4); +FastPWM motor1_pwm(D5); +DigitalOut motor2_dir(D7); +FastPWM motor2_pwm(D6); -// waardes die komen van Charlotte: true is aangespannen, false is niet aangespannen (NAAM CONTROLEREN) -volatile bool BicepsLinks = false; -volatile bool BicepsRechts = true; -volatile bool Been = false; +// Set LED pins +DigitalOut led(LED_RED); -// nodig voor het switchstatement -enum states {Flipper, Links, Rechts, Voor, Achter, GeenSignaal}; -states MyState = Links; +// Set HID scope +HIDScope scope(2); -// het bepalen van welke case we hebben -void CaseBepalen () { - if (BicepsLinks==true && BicepsRechts==true && Been==true && BezigMetFlippen == false) { - MyState = Flipper; // flipper bewegen - } - else if (BicepsLinks==true && BicepsRechts==false && Been==false && BezigMetFlippen == false) { - MyState = Links; // naar links bewegen - } - else if (BicepsLinks==false && BicepsRechts==true && Been==false && BezigMetFlippen == false) { - MyState = Rechts; // naar rechts bewegen - } - else if (BicepsLinks==true && BicepsRechts==true && Been==false && BezigMetFlippen == false) { - MyState = Voor; // naar voren bewegen - } - else if (BicepsLinks==false && BicepsRechts==true && Been==true && BezigMetFlippen == false) { - MyState = Achter; // naar achter bewegen - } - else if (BicepsLinks==false && BicepsRechts==false && Been==false || BezigMetFlippen==true) { - MyState = GeenSignaal; - } -} +// Set Encoders for motors +QEI Motor1_ENC_CW(D11,D10,NC,32); +QEI Motor1_ENC_CCW(D10,D11,NC,32); +QEI Motor2_ENC_CW(D12,D13,NC,32); +QEI Motor2_ENC_CCW(D13,D12,NC,32); + +// Constants +volatile double pwm = 0.0; +volatile double pwm_new = 0; +volatile double timer = 0.0; +volatile bool button1_value = false; +volatile bool button2_value = false; -// het berekenen van de nieuwe x en y en zorgen dat deze niet buiten het bereik komen -void VeranderenXY () { - // bepalen hoe de x en y waardes gaan veranderen - switch(MyState) { - case Flipper : - BeginnenMetFlippen = true; // we zijn aan het flipper dus geen andere dingen doen - break; - case Links : - vorigex = x; // ervoor zorgen dat als de motor te ver draait de x niet verder telt - x = x - Step; - break; - case Rechts : - vorigex = x; - x = x + Step; - break; - case Voor : - vorigey = y; // ervoor zorgen dat als de motor te ver draait de y niet verder telt - y = y + Step; - break; - case Achter : - vorigey = y; - y = y - Step; - break; - case GeenSignaal : - break; - default : - pc.printf("Er is geen verandering in x en y\r\n"); - } - - // Grenswaardes LET OP: ARMEN MISSCHIEN GEBLOKKEERD DOOR BALK AAN DE BINNENKANT - if (x > 200) { - x = 200; - } - else if (x < -200) { - x = -200; - } - if (y > 306) { - y = 306; - } - else if (y < 50) { - y = 50; // GOKJE, UITPROBEREN - } - pc.printf("x = %f, y = %f\r\n", x, y); +// Ticker +Ticker SinTicker; +Ticker PotControlTicker; +Ticker SendZerosTicker; + +void SwitchLed() +{ + led = not led; +} + +void button1_switch() +{ + button1_value = not button1_value; +} + +void button2_switch() +{ + button2_value = not button2_value; } -// functie om D1 en D2 te berekenen -void AfstandBerekenen (){ - float BV1 = sqrt(pow((a+x),2) + pow(y,2)); // diagonaal (afstand van armas tot locatie) berekenen - Dia1 = pow(BV1,2)/(2*BV1); // berekenen van de afstand oorsprong tot diagonaal - - float BV2 = sqrt(pow((x-a),2) + pow(y,2)); // zelfde nog een keer doen maar nu voor de rechter arm - Dia2 = pow(BV2,2)/(2*BV2); - - //pc.printf("Dia1 = %f, Dia2 = %f\r\n", Dia1, Dia2); +void SendZeros() +{ + int zero=0; + scope.set(0,zero); + scope.set(1,zero); + scope.send(); } -// functie om de motorhoek te berekenen -void MotorHoekBerekenen (){ - // eerst if loop doorlopen voor motor 1 - if (x > -a) { - MotorHoek1 = pi - atan(y/(x+a)) - acos(Dia1/Bar); - } - else if (x > -a) { - MotorHoek1 = pi - (pi + atan(y/(x+a))) - acos(Dia1/Bar); - } - else { // als x=-a - MotorHoek1 = 0.5f*pi - acos(Dia1/Bar); - } - // twee if loop doorlopen voor motor 2 - if (x < a) { - MotorHoek2 = pi + atan(y/(x-a)) - acos(Dia2/Bar); - } - else if (x > a) { - MotorHoek2 = pi - (pi - atan(y/(x-a))) - acos(Dia2/Bar); - } - else { // als x=a - MotorHoek2 = 0.5f*pi - acos(Dia1/Bar); - } - - // limiten (als de hoek te groot wordt, reset dan de hoek en de x en y waardes) - if (MotorHoek1 >= MaxHoek) { // is de maximale hoek in radialen - MotorHoek1 = VorigeHoek1; - x = vorigex; - y = vorigey; - } - if (MotorHoek2 >= MaxHoek) { - MotorHoek2 = VorigeHoek2; - x = vorigex; - y = vorigey; +void SetMotor(int motor_number, double MotorValue) +{ + // Given -1<=motorValue<=1, this sets the PWM and direction + // bits for motor 1. Positive value makes motor rotating + // clockwise. motorValues outside range are truncated to + // within range + if (motor_number == 1) + { + if (MotorValue >=0) + { + motor1_dir=1; + } + else + { + motor1_dir=0; + } + if (fabs(MotorValue)>1){ + motor1_pwm.write(1); + } + else + { + motor1_pwm.write(abs(MotorValue)); + } } - //pc.printf("MotorHoek1 = %f en MotorHoek2 = %f \r\n", MotorHoek1, MotorHoek2); -} - -// het verschil uitrekenen tussen waar we zijn en waar we heen willen OVERLAP MET SJOERD -void BerekenenBewegingsHoek () { - // Hoek 1: grootte beweging en richting - BewegingsHoek1 = VorigeHoek1 - MotorHoek1; - VorigeHoek1 = MotorHoek1; - if (BewegingsHoek1 > 0) { - Richting1 = false; // ccw - } - else { - Richting1 = true; // cw + else + { + if (MotorValue >=0) + { + motor1_dir=1; + } + else + { + motor1_dir=0; + } + if (fabs(MotorValue)>1){ + motor1_pwm.write(1); + } + else + { + motor1_pwm.write(abs(MotorValue)); + } } - - // Hoek 2: grootte beweging en richting - BewegingsHoek2 = VorigeHoek2 - MotorHoek2; - VorigeHoek2 = MotorHoek2; - if (BewegingsHoek2 > 0) { - Richting2 = true; // cw - } - else { - Richting2 = false; // ccw + +} + +double GetPosition(int motor_number) +{ + const int COUNTS_PER_REV = 8400; + const float DEGREES_PER_PULSE = 8400 / 360; + if (motor_number == 1) + { + int countsCW = Motor1_ENC_CW.getPulses(); + int countsCCW= Motor1_ENC_CCW.getPulses(); + int net_counts = countsCW-countsCCW; + double Position=(net_counts*360.0f)/COUNTS_PER_REV; + return Position; } - //pc.printf("Beweging 1 = %f, Beweging 2 = %f\r\n", BewegingsHoek1, BewegingsHoek2); -} - -// als BeginnenMetFlippen aan staat voeren we deze functie uit. Zolang deze bezig is is BezigMetFlippen true -void FlipperBewegen () { - if (BeginnenMetFlippen == true) { - // SJOERDS DEEL - } - else { // als BezigMetFlippen == false dan doe niks + else + { + int countsCW = Motor2_ENC_CW.getPulses(); + int countsCCW= Motor2_ENC_CCW.getPulses(); + int net_counts = countsCW-countsCCW; + double Position=(net_counts*360.0f)/COUNTS_PER_REV; + return Position; } } -// als de button ingedrukt wordt dan stoppen we met calibreren -void ButtonIndrukken () { - BezigMetCalibreren = false; -} - +void MultiSin_motor1() +{ + double pwm = pwm_new; + double f1 = 0.2f; + double f2 = 1.0f; + double f3 = 5.0f; + double f4 = 20.0f; + double f5 = 100.0f; + const double pi = 3.141592653589793238462; + // read encoder + double motor1_position = GetPosition(1); + // set HIDSCOPE values, position, pwm*volt + scope.set(0, motor1_position); + scope.set(1, pwm); + // sent HIDScope values + scope.send(); + // calculate the new multisin + double multisin = sin(2*pi*f1*timer)+sin(2*pi*f2*timer)+sin(2*pi*f3*timer)+sin(2*pi*f4*timer)+sin(2*pi*f5*timer); + // devide by the amount of sin waves + pwm_new=multisin / 5; + // write the motors + SetMotor(1, multisin); + // Increase the timer + timer = timer + 0.001; + if (timer >= (20.0-0.001)) + { + SinTicker.detach(); + timer = 0; + } +} + +void MultiSin_motor2() +{ + double pwm = pwm_new; + double f1 = 0.2f; + double f2 = 1.0f; + double f3 = 5.0f; + double f4 = 20.0f; + double f5 = 100.0f; + const double pi = 3.141592653589793238462; + // read encoder + double motor2_position = GetPosition(2); + // set HIDSCOPE values, position, pwm*volt + scope.set(0, motor2_position); + scope.set(1, pwm); + // sent HIDScope values + scope.send(); + // calculate the new multisin + double multisin = sin(2*pi*f1*timer)+sin(2*pi*f2*timer)+sin(2*pi*f3*timer)+sin(2*pi*f4*timer)+sin(2*pi*f5*timer); + // devide by the amount of sin waves + pwm_new=multisin / 5; + // write the motor + SetMotor(2, multisin); + // Increase the timer + timer = timer + 0.001; + if (timer >= (20.0-0.001)) + { + SinTicker.detach(); + timer = 0; + } +} + +void PotControl() +{ + double Motor1_Value = (pot1.read() - 0.5)/2.0; + double Motor2_Value = (pot2.read() - 0.5)/2.0; + //pc.printf("\r\n Motor value 1: %f \r\n",Motor1_Value); + //pc.printf("\r\n Motor value 2: %f \r\n",Motor2_Value); + scope.set(0, Motor1_Value); + scope.set(1, Motor2_Value); + scope.send(); + // Write the motors + SetMotor(1, Motor1_Value); + SetMotor(2, Motor2_Value); +} + +void SinControl1() +{ + SinTicker.attach(&MultiSin_motor1, 0.001); +} + +void SinControl2() +{ + SinTicker.attach(&MultiSin_motor2, 0.001); +} + +void HIDScope_Send() +{ + scope.send(); +} + + + int main() { pc.baud(SERIAL_BAUD); - pc.printf("\r\n Nieuwe code uitproberen :) \r\n"); + pc.printf("\r\n ***THERMONUCLEAR WARFARE HAS COMMENCED*** \r\n"); + + // Set LED + led=0; + Ticker LedTicker; + LedTicker.attach(SwitchLed,0.5f); + + // Interrupt for buttons + button1.fall(button1_switch); + button2.fall(button2_switch); + + pc.printf("\r\n ***************** \r\n"); + pc.printf("\r\n Press button 1 to start positioning the arms \r\n"); + pc.printf("\r\n Make sure both potentiometers are positioned halfway! \r\n"); + pc.printf("\r\n ***************** \r\n"); + while (button1_value == false) + { + // just wait + } + pc.printf("\r\n ***************** \r\n"); + pc.printf("\r\n Use potentiometers to control the motor arms \r\n"); + pc.printf("\r\n Pot 1 for motor 1 \r\n"); + pc.printf("\r\n Pot 2 for motor 2 \r\n"); + pc.printf("\r\n ***************** \r\n"); + pc.printf("\r\n Press button 2 to start the rest of the program \r\n"); + pc.printf("\r\n ***************** \r\n"); + // Start potmeter control + PotControlTicker.attach(&PotControl,0.01f); - // calibreren gebeurt hier, zodat de tickers nog niet lopen en dit dus geen rekenkracht kost en je niet gebonden bent aan tijden - // we gaan door met calibreren tot we de button indrukken - while (BezigMetCalibreren == true) { - // potmeter dingen aanpassen - - pc.printf("calibreren is bezig\r\n"); - Button1.fall(&ButtonIndrukken); + while (button2_value == false) + { + // just wait + } + PotControlTicker.detach(); + SendZerosTicker.attach(&SendZeros,0.001); + + // Program startup + pc.printf("\r\n Starting multisin on motor 1 in: \r\n"); + pc.printf("\r\n 10 \r\n"); + wait(5); + pc.printf("\r\n 5 \r\n"); + wait(1); + pc.printf("\r\n 4 \r\n"); + wait(1); + pc.printf("\r\n 3 \r\n"); + wait(1); + pc.printf("\r\n 2 \r\n"); + wait(1); + pc.printf("\r\n 1 \r\n"); + wait(1); + pc.printf("\r\n 0 \r\n"); + pc.printf("\r\n Wait for the signal to complete \r\n"); + pc.printf("\r\n Press button 2 too continue afterwards \r\n"); + SendZerosTicker.detach(); + SinControl1(); + + + while (button2_value == true) + { + // just wait } - TickerCaseBepalen.attach(&CaseBepalen, 1); // ticker om te bepalen welke case we gaan gebruiken - TickerVeranderenXY.attach(&VeranderenXY,1); // ticker voor het veranderen van de x en y waardes - TickerAfstandBerekenen.attach(&AfstandBerekenen,1); // ticker om de waardes van dia1 en dia 2 te berekenen - TickerMotorHoekBerekenen.attach(&MotorHoekBerekenen,1); // ticker om de motorhoek te berekenen - TickerBerekenenBewegingsHoek.attach(&BerekenenBewegingsHoek,1); // ticker om grote en richting vd beweging te berekenen - TickerFlipperBewegen.attach(&FlipperBewegen,1); // ticker om de flipper te laten bewegen - while (true) { - - } + SendZerosTicker.attach(&SendZeros,0.001); + pc.printf("\r\n Starting multisin on motor 2 in: \r\n"); + pc.printf("\r\n 10 \r\n"); + wait(5); + pc.printf("\r\n 5 \r\n"); + wait(1); + pc.printf("\r\n 4 \r\n"); + wait(1); + pc.printf("\r\n 3 \r\n"); + wait(1); + pc.printf("\r\n 2 \r\n"); + wait(1); + pc.printf("\r\n 1 \r\n"); + wait(1); + pc.printf("\r\n 0 \r\n"); + SendZerosTicker.detach(); + SinControl2(); + wait(23); + pc.printf("\r\n Program Finished, press reset to restart \r\n"); + while (true) {} }