Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: HIDScope MODSERIAL QEI TextLCD mbed
Fork of TotalControlEmg2 by
Diff: main.cpp
- Revision:
- 24:ddd69385b55f
- Parent:
- 23:855c4bcb2284
- Child:
- 25:c97d079e07f3
diff -r 855c4bcb2284 -r ddd69385b55f main.cpp
--- a/main.cpp Thu Oct 15 10:16:44 2015 +0000
+++ b/main.cpp Thu Oct 15 11:13:32 2015 +0000
@@ -1,34 +1,69 @@
#include "mbed.h"
+#include "QEI.h"
+#include "MODSERIAL.h"
+#include "TextLCD.h"
#include "HIDScope.h"
#include "Filterdesigns.h"
#include "Kalibratie.h"
-#include "MODSERIAL.h" //bugfix
#include "Mode.h"
-
-AnalogIn emg(A0); //Analog input van emg kabels
+//--------------------Classes------------------------
+InterruptIn btnSet(PTC6); // kalibreer knop
+DigitalOut ledR(LED_RED); // Led op moederbord
+MODSERIAL pc(USBTX, USBRX); // Modserial voor Putty
+TextLCD lcd(PTC5, PTC7, PTC0, PTC9, PTC8, PTC1); // LCD scherm op binnenste rij van K64F, rs, e, d4-d7
+PwmOut servo(D3); // PwmOut servo
+AnalogIn btnL(A2), btnR(A3); // push buttons, links en rechts
+AnalogIn ptmrL(A2), ptmrR(A3); // Intensiteit 'EMG' signaal door potmeter
+AnalogIn KS(A4); // Killswitch
+Ticker tickerRegelaar, tickerBtn, tickerRem; // regelaar button en rem ticker
+Timer EMGTimer; // timer voor EMG meting
+// EMG spul:
+AnalogIn emg(A0); //Analog input van emg kabels Links
+AnalogIn emgR(A1); //Analog input van emg kabels Rechts
HIDScope scope(3); //3 scopes
Ticker EMGticker;
-MODSERIAL pc(USBTX, USBRX); //bugfix
DigitalOut LedBlue(LED3);
DigitalIn button(PTA4);
+// QEI Encoder(poort 1, poort 2, ,counts/rev
+ QEI enc1 (D13, D12, NC, 64);
+ QEI enc2 (D11, D10, NC, 64);
+// Motor1 met PWM aansturen en richting aangeven
+ PwmOut pwmM1(D6);
+ DigitalOut dirM1(D7);
+// Motor2 met PWM aansturen en richting aangeven
+ PwmOut pwmM2(D5);
+ DigitalOut dirM2(D4);
+
+enum spelfase {KALIBRATE_EMG1, KALIBRATE_AIM, KALIBRATE_PEND, AIM, REM, FIRE}; // Spelfases, ACKNOWLEDGEMENT: BMT groep 4 2014
+uint8_t state = KALIBRATE_EMG1; // eerste spelfase
+
+enum aimFase {OFF, CW, CCW}; // Aim motor mogelijkheden
+uint8_t aimState = OFF; // mogelijkheid begin
+//-------------------------------Variables---------------------------------------------------------------------
+const double servoL = 0.001, servoR = 0.0011; // uitwijking servo, bereik tussen L en R (= pulsewidth pwm servo)
+const int on = 0, off = 1; // aan / uit
+volatile bool btn = false; // boolean om programma te runnen, drukknop ingedrukt
+int maxCounts = 2100; // max richt motor counts Aim motor
+volatile bool regelaarFlag = false, btnFlag = false, remFlag = false; // Go flags
+const double tRegelaar = 0.005, tBtn = 0.005, tRem = 0.1; // tijd ticker voor regelaar en knoppen/EMG
+int remPerc = 0;
+volatile bool L = false, R = false; // Booleans voor knop link en knop rechts
+volatile int emgModeL = 1, emgModeR = 1; // emg signaal waarden
+
//Sample frequentie
double Fs = 200; //Hz
double t = 1/ Fs; // voor EMGticker
-bool readymax = 0;
-bool readymin = 0;
-double ymin;
-double ymax;
-double thresholdlow;
-double thresholdmid;
-double thresholdhigh;
-bool go_flag = 0;
+bool readymax = 0, readymin = 0;
+double ymin, ymax;
+double thresholdlow, thresholdmid, thresholdhigh;
+bool go_flag = false;
-void EMGkalibratie()
-{
+//----------------------------Functions-----------------------------------------------------------------------
+void EMGkalibratie(){
LedBlue = 1;
- Init();
+ Init();
ymin = KalibratieMin(readymin);
wait(1);
ymax = KalibratieMax(readymax);
@@ -39,43 +74,274 @@
thresholdhigh = 0.8 * ymax;
pc.printf("ymax = %f en ymin = %f \n",ymax, ymin); //bugfix
-}
+ }
-void EMGfilter()
-{
+void EMGfilter(){
//uitlezen emg signaal
double u = emg.read();
double y = Filterdesigns(u);
//pc.printf("%f \n",y); //bugfix
// Plotten in HIDscope
- int mode = Mode(y, ymax, thresholdlow, thresholdmid, thresholdhigh); //bepaald welk signaal de motor krijgt (aan, uit, middel)
+ emgModeL = Mode(y, ymax, thresholdlow, thresholdmid, thresholdhigh); //bepaald welk signaal de motor krijgt (aan, uit, middel)
scope.set(0,u); //ongefilterde waarde naar scope 1
scope.set(1,y); //gefilterde waarde naar scope 2
- scope.set(2,mode);
+ scope.set(2,emgModeL);
scope.send(); //stuur de waardes naar HIDscope
-}
-
-void Go_flag(){
- go_flag = 1;
}
-int main()
-{
- //pc.baud(115200);
- EMGticker.attach(&Go_flag, t); //500H
- while(1) {
- if(go_flag) { // als deze true is dan gaat hij de onderstaande gebeuren aan
- go_flag = 0;
- if(button == 0) {
- readymax = 0;
- readymin = 0;
- }
- else if(readymax == 0 || readymin == 0) {
+void Go_flag(){
+ go_flag = true;
+ }
+// -----
+
+void flipLed(DigitalOut& led){ //function to flip one LED
+ led.write(on);
+ wait(0.2);
+ led.write(off);
+ }
+void PRINT(const char* text){ // putty en lcd print
+ lcd.cls(); // clear LCD scherm
+ lcd.printf(text); // print text op lcd
+ pc.printf(text); // print text op terminal
+ }
+void btnSetAction(){ // Set knop K64F
+ btn = true; // GoFlag setknop
+ }
+void setBtnFlag(){ // Go flag regelaar Aim motor
+ btnFlag = true;
+ }
+void setRegelaarFlag(){ // Go flag button controle
+ regelaarFlag = true;
+ }
+void setRemFlag(){ // Go flag rem
+ remFlag = true;
+ }
+void checkAim(){ // controleer of killer switch geraakt is en of max aantal counts niet bereikt is
+ double volt = KS.read();
+ if(volt< 0.5 /*|| abs(enc2.getPulses()) > maxCounts*/){
+ pwmM2.write(0); // Aim motor stilzetten
+ pc.printf("BOEM! CRASH! KASTUK! \r\n");
+ }
+ }
+void motorAim(int dir){ // Aim motor laten draaien met gegeven direction
+ dirM2.write(dir); // richting
+ pwmM2.write(0.5); // width aanpassen
+ }
+bool controlAim(){ // Function om aim motor aan te sturen
+ bool both = false; // boolean of beide knoppen ingedrukt zijn
+
+ if(!(ptmrL.read() >0.3 && ptmrR.read()>0.3) != !(emgModeL!=1 && emgModeR!=1)) { // Potmeters L en R beide aan XOR EMG beide aangespannen
+ R = false;
+ L = false;
+ pwmM2.write(0); // Aim motor stilzetten
+ aimState = OFF;
+ }
+ else if(!(ptmrL.read() >= 0.8 != !(emgModeL == 3)) && L) { // Potmeter L vol ingedrukt XOR emgModeL is 3
+ both = true; // Return true
+ pwmM2.write(0); // Aim motor stilzetten
+ aimState = OFF;
+ L = false;
+ }
+ else if((!(ptmrR.read() > 0.8) != !(emgModeR == 3)) && aimState!=OFF) { // Potmeter R vol ingedrukt XOR emgModeR == 3
+ R = false;
+ pwmM2.write(0); // Aim motor stilzetten
+ aimState = OFF;
+ PRINT("Motor freeze\r\n");
+ }
+ else if((!(ptmrL.read() > 0.3 && ptmrL.read() < 0.6) != !(emgModeL == 2)) && aimState != CCW && L) { // Potmeter L half XOR emgModeL ==2 AND richting is niet CCW
+ aimState = CCW; // draai CCW
+ pc.printf("Turn negative (CCW)\r\n");
+ motorAim(0);
+ }
+ else if((!(ptmrR.read() > 0.3 && ptmrR.read() < 0.6) != !(emgModeR == 2)) && aimState != CW && R) { // Potmeter R half XOR emgModeR == 2 AND richting is niet CW
+ aimState = CW; // draai CW
+ PRINT("Turn positive (CW)\r\n");
+ motorAim(1);
+ }
+ if(ptmrR.read() < 0.1 && emgModeR == 1 && !R){ // R is niet aan
+ R = true;
+ }
+ if(ptmrL.read() < 0.1 && emgModeL == 1 && !L){ // L is niet aan
+ L = true;
+ }
+ return both;
+ }
+int main(){
+ flipLed(ledR); // test of code begint
+ btnSet.mode(PullUp); // Button mode
+ btnSet.rise(&btnSetAction); // Setknop aan functie koppellen
+ tickerRegelaar.attach(&setRegelaarFlag,tRegelaar); // ticker regelaar motor
+ tickerBtn.attach(&setBtnFlag,tBtn); // ticker knop controle
+ tickerRem.attach(&setRemFlag,tRem); // ticker rem
+
+ EMGticker.attach(&Go_flag, t); // ticker EMG, 500H
+
+ lcd.cls();
+ lcd.printf("NEW GAME \n HELLO!");
+
+ pc.printf("\n\n\n\n\n");
+ pc.printf("--- NEW GAME ---\r\n");
+ while(1){ // Programma door laten lopen
+ switch(state){
+ case KALIBRATE_EMG1: {
+ pc.printf("Kalibrate EMG signal in 5 seconds\r\n");
+ lcd.cls();
+ lcd.printf("Kalibrate EMG\n in 5 sec.");
+
EMGkalibratie();
- }
- else if(readymax == 1 && readymin == 1) {
- EMGfilter();
+
+ state = KALIBRATE_AIM;
+ break;
+ }
+ case KALIBRATE_AIM: {
+ pwmM2.period(1/100000); // aanstuurperiode motor 2
+ PRINT("Kalibrate aim motor\r\n");
+ wait(1);
+ pc.printf("Use L and R to move pendulum to equilibruim position\r\n L+R = OK\r\n");
+ while(state==KALIBRATE_AIM){
+ if(regelaarFlag){ // motor regelen op GoFlag
+ regelaarFlag = false;
+ checkAim(); // Controleer positie
+ }
+
+ if(go_flag){ // Go flag EMG sampelen
+ go_flag = false;
+ EMGfilter();
+ }
+ if(btnFlag){ // Go flag button controle?
+ btnFlag = false;
+ if(controlAim()){ // Buttons met control, if true = beide knoppen = bevestigen
+ enc2.reset(); // resetknop = encoder 1 resetten
+ pc.printf("Positie gekalibreerd, kalibreer nu slinger, encoder counts: %i\r\n", enc2.getPulses());
+ state = KALIBRATE_PEND; // volgende state
+ }
+ }
+ }
+ break;
+ }
+ case KALIBRATE_PEND: {
+ pc.printf("Kalibrate pendulum motor with setknop\r\n");
+ pwmM1.period(1/100000); // aanstuurperiode motor 1
+ servo.period(0.02); // 20ms period aanstuurperiode
+ pwmM1.write(0.5); // Motor aanzetten, laag vermogen
+ btn = false;
+ while(state==KALIBRATE_PEND){
+ if(btnFlag){
+ pc.printf(""); // lege regel printen, anders doet setknop het niet
+ btnFlag = false;
+ if (btn){ // Als setknop ingedrukt is reset
+ pwmM1.write(0); // Motor 1 stilzetten
+ enc1.reset(); // encoder 1 resetten
+ pc.printf("Pendulum kalibrated\r\n");
+ btn = false; // knop op false
+ state = AIM; // volgende fase
+ }
+ }
+ }
+ break;
+ }
+ case AIM: {
+ pc.printf("Aim with EMG\r\n");
+ while(state == AIM){
+ if(regelaarFlag){ // motor regelen op GoFlag
+ regelaarFlag = false;
+ checkAim(); // Controleer positie
+ }
+ if(go_flag){ // Go flag EMG sampelen
+ go_flag = false;
+ EMGfilter();
+ }
+ if(btnFlag){ // Go flag button controle?
+ btnFlag = false;
+ if(controlAim()){
+ pc.printf("Position choosen, adjust shoot velocity\r\n");
+ state = REM; // volgende state (REM)
+ }
+ }
+ }
+ break;
+ }
+ case REM: {
+ pc.printf("Set break percentage, current is: %.0f\r\n", remPerc);
+ L = false;
+ R = false;
+ while(state == REM){
+ if(go_flag){ // Go flag EMG sampelen
+ go_flag = false;
+ EMGfilter();
+ }
+ if(btnFlag){ // Go flag button controle? == rem aansturen
+ btnFlag = false;
+
+ if((ptmrR.read() < 0.1)) { // R is niet aan
+ R = true;
+ }
+ if((ptmrL.read() < 0.1)) { // L is niet aan
+ L = true;
+ }
+ if(L && R){
+ if(!(ptmrL.read() >0.3 && ptmrR.read()>0.3) != !(emgModeL!=1 && emgModeR!=1)) { // beide aangespannenR = false;
+ state = FIRE;
+ }
+ else if(!(ptmrL.read() >= 0.8 != !(emgModeL == 3))) { // links vol ingedrukt = schieten
+ state = FIRE;
+ }
+ else if(!(ptmrR.read() > 0.8) != !(emgModeR == 3)) { //rechts vol ingedrukt = schieten
+ state = FIRE;
+ }
+ else if((!(ptmrL.read() > 0.3 && ptmrL.read() < 0.6) != !(emgModeL == 2)) && L) { // links ingedrukt = rem verlagen
+ if(remPerc>1){
+ remPerc--; // Rem percentage verlagen met 1
+ }
+ L = false;
+
+ }
+ else if((!(ptmrR.read() > 0.3 && ptmrR.read() < 0.6) != !(emgModeR == 2)) && R) { // Rechts half ingedrukt = rem verhogen
+ if(remPerc<9){
+ remPerc++; // rem percentage verhogen met 1
+ }
+ R = false;
+ }
+
+ if((ptmrL.read() > 0.3 || ptmrR.read() > 0.3) || (emgModeL != 1 || emgModeR !=1)){ // Print rem scale als een of beide knoppen aan zijn
+ pc.printf("Current breaking scale: %i\r\n", abs(remPerc));
+ }
+ }
+ }
+ }
+ L = false;
+ R = false;
+ break;
+ }
+ case FIRE: {
+ pc.printf("Shooting\r\n");
+ servo.pulsewidth(servoL); // schrijfrem release
+ pwmM1.write(0.5); // motor aanzetten
+ bool servoPos = true;
+ while(state == FIRE){ // Zolang in FIRE state
+ if(remFlag && (abs(enc1.getPulses())-100)%4200 < (2100*abs(remPerc)/10)){ // Rem goFlag en half rondje = remmen
+ remFlag = false;
+ if(servoPos){ //
+ servoPos = false;
+ servo.pulsewidth(servoL); // links
+ }
+ else{
+ servoPos = true;
+ servo.pulsewidth(servoR); // rechts
+ }
+ }
+ if(regelaarFlag){
+ regelaarFlag = false;
+ //pc.printf("Slinger encoder: %i\r\n", enc1.getPulses()%4200);
+ if((abs(enc1.getPulses())+50)%4200 < 150){ // Slinger 1 rondje laten draaien
+ pwmM1.write(0); // motor uitzetten
+ pc.printf("Pendulum on startposition\r\n");
+ state = AIM; // Aim is volgende fase
+ }
+ }
+ }
+ break;
+ }
}
}
- }
-}
+ }
\ No newline at end of file
