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: mbed QEI HIDScope biquadFilter MODSERIAL FastPWM
main.cpp
- Committer:
- joostbonekamp
- Date:
- 2019-10-10
- Revision:
- 16:696e9cbcc823
- Parent:
- 15:9a1f34bc9958
- Child:
- 17:615c5d8b3710
File content as of revision 16:696e9cbcc823:
#include "mbed.h"
#include "MODSERIAL.h"
#include "FastPWM.h"
#include "QEI.h"
#define PI 3.14159265
Serial pc(USBTX, USBRX); //connect to pc
DigitalOut motor1_direction(D4); //rotation motor 1 on shield (always D6)
FastPWM motor1_pwm(D5); //pwm 1 on shield (always D7)
DigitalOut motor2_direction(D7); //rotation motor 2 on shield (always D4)
FastPWM motor2_pwm(D6); //pwm 2 on shield (always D5)
Ticker loop_ticker; //used in main()
AnalogIn Pot1(A1); //pot 1 on biorobotics shield
AnalogIn Pot2(A0); //pot 2 on biorobotics shield
InterruptIn but1(D10); //debounced button on biorobotics shield
InterruptIn but2(D9); //debounced button on biorobotics shield
AnalogIn EMG1(A2);
AnalogIn EMG2(A3);
QEI encoder1 (D11, D12, NC, 8400, QEI::X4_ENCODING); //encoder 1 gebruiken
QEI encoder2 (D1, D2, NC, 8400, QEI::X4_ENCODING); //encoder 2 gebruiken
//variables
enum States {idle, cali_EMG, cali_enc, moving_magnet_off, moving_magnet_on, homing, failure};
States state; //using the States enum
struct actuator_state {
float duty_cycle1; //pwm of 1st motor
float duty_cycle2; //pwm of 2nd motor
int dir1; //direction of 1st motor
int dir2; //direction of 2nd motor
bool magnet; //state of the magnet
} actuators;
struct EMG_params {
float max; //params of the emg, tbd during calibration
} EMG_values;
int enc1_zero; //the zero position of the encoders, to be determined from the
int enc2_zero; //encoder calibration
int EMG1_filtered;
int EMG2_filtered;
int enc1_value;
int enc2_value;
//variables used throughout the program
bool state_changed = false; //used to see if the state is "starting"
volatile bool but1_pressed = false;
volatile bool but2_pressed = false;
volatile bool failure_occurred = false;
float pot_1; //used to keep track of the potentiometer values
float pot_2;
bool enc_has_been_calibrated;
bool EMG_has_been_calibrated;
void do_nothing()
/*
Idle state. Used in the beginning, before the calibration states.
*/
{
if (button1_pressed) {
state_changed = true;
state = cali_enc;
button1_pressed = false;
}
}
void failure()
/*
Failure mode. This should execute when button 2 is pressed during operation.
*/
{
if (state_changed) {
pc.printf("Something went wrong!\r\n");
state_changed = false;
}
}
void cali_EMG()
/*
Calibration of the EMG. Values determined during calibration should be
added to the EMG_params instance.
*/
{
if (state_changed) {
pc.printf("Started EMG calibration\r\n");
state_changed = false;
}
}
void cali_enc()
/*
Calibration of the encoder. The encoder should be moved to the lowest
position for the linear stage and the most upright postition for the
rotating stage.
*/
{
if (state_changed) {
pc.printf("Started encoder calibration\r\n");
state_changed = false;
}
if (button1_pressed) {
enc1_zero = enc1_value;
enc2_zero = enc2_value;
enc_has_been_calibrated = true;
button1_pressed = false;
state = moving_magnet_off;
state_changed = true;
}
}
void moving_magnet_off()
/*
Moving with the magnet disabled. This is the part from the home position
towards the storage of chips.
*/
{
if (state_changed) {
pc.printf("Moving without magnet\r\n");
state_changed = false;
}
}
void moving_magnet_on()
/*
Moving with the magnet enabled. This is the part of the movement from the
chip holder to the top of the playing board.
*/
{
if (state_changed) {
pc.printf("Moving with magnet\r\n");
state_changed = false;
}
return;
}
void homing()
/*
Dropping the chip and moving towards the rest position.
*/
{
if (state_changed) {
pc.printf("Started homing");
state_changed = false;
}
return;
}
void measure_signals()
{
enc1_value = enc1.getPulses();
enc2_value = enc2.getPulses();
if (enc_has_been_calibrated) {
enc1_value -= enc1_zero;
enc2_value -= enc2_zero;
}
EMG1_raw = EMG1.read();
EMG2_raw = EMG2.read();
}
void output()
{
motor1_direction = actuator.dir1;
motor2_direction = acuator.dir2;
motor1_pwm.write(actuator.pwm1);
motor2_pwm.write(actuator.pwm2);
}
void state_machine()
{
check_failure(); //check for an error in the last loop before state machine
//run current state
switch (current_state) {
case idle:
do_nothing();
break;
case failure:
failure();
break;
case cali_EMG:
cali_EMG();
break;
case cali_ENC:
cali_encoder();
break;
case moving_magnet_on:
moving_magnet_on();
break;
case moving_magnet_off:
moving_magnet_off();
break;
case homing:
homing();
break;
}
}
void main_loop()
{
measure_signals();
state_machine();
motor_controller();
output();
}
//Helper functions, not directly called by the main_loop functions or
//state machines
void check_failure()
{
state = failure;
state_changed = true;
}
void but1_interrupt()
{
if(button2.read()) {//both buttons are pressed
failure_occurred = true;
}
but1_pressed = true;
pc.printf("Button 1 pressed \n\r");
}
void but2_interrupt()
{
if(button1.read()) {//both buttons are pressed
failure_occurred = true;
}
but2_pressed = true;
pc.printf("Button 2 pressed \n\r");
}
int schmitt_trigger(float i)
{
speed = -1; //default value, this means the state should not change
float levels = 5.0;
if (i > 0/14 && i < 2/14) {speed = 0;}
if (i > 3/14 && i < 5/14) {speed = 1;}
if (i > 6/14 && i < 8/14} (speed = 2;}
if (i > 9/14 && i < 11/14) {speed = 3;}
if (i > 12/14 && i < 14/14) {speed = 4;}
return speed;
}
int main()
{
pc.baud(115200);
pc.printf("Executing main()... \r\n");
current_state = idle;
motor2_pwm.period(1/160000f); // 1/frequency van waarop hij draait
motor1_pwm.period(1/160000f); // 1/frequency van waarop hij draait
actuator.dir1 = 0;
actuator.dir2 = 0;
actuator.magnet = false;
but1.fall(&but1_interrupt);
but2.fall(&but2_interrupt);
loop_ticker.attach(&main_loop, 0.001f); //main loop at 1kHz
pc.printf("Main_loop is running\n\r");
while (true) {
wait(0.1f);
}
}]