eLab Team / Mbed 2 deprecated LaLaBox

Dependencies:   mbed CREALIB

Committer:
garphil
Date:
Fri Jun 17 10:48:18 2016 +0000
Revision:
1:ab4c9a0a5374
Parent:
0:30cb0f6dad87
Child:
2:050f12806bc5
Imported Winder and libs from ws2812;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
garphil 1:ab4c9a0a5374 1 #include "LaLaBox.h"
garphil 1:ab4c9a0a5374 2
garphil 1:ab4c9a0a5374 3 // ---------------- Local global variables --------------
garphil 1:ab4c9a0a5374 4 DigitalOut myled(LED1); // Blinking LED
garphil 1:ab4c9a0a5374 5 // -------------------- Motor ---------------------------
garphil 1:ab4c9a0a5374 6 Ticker MotorSystemTick; // System Callback for Motor
garphil 1:ab4c9a0a5374 7 timestamp_t MotorStepTime; // Time in µs for one motor step
garphil 1:ab4c9a0a5374 8 uint32_t MotorFullTurn; // Number of step for a complete turn
garphil 1:ab4c9a0a5374 9 uint32_t NumWires; // Number of Wires
garphil 1:ab4c9a0a5374 10 uint32_t NumSteps; // Number of Steps = NumWire * MotorFullTurn
garphil 1:ab4c9a0a5374 11
garphil 1:ab4c9a0a5374 12 enum MotorStateList { // Define Motor States for the State Machine
garphil 1:ab4c9a0a5374 13 Motor_IDLE = 0,
garphil 1:ab4c9a0a5374 14 Motor_RUN,
garphil 1:ab4c9a0a5374 15 Motor_PAUSE,
garphil 1:ab4c9a0a5374 16 Motor_ZERO,
garphil 1:ab4c9a0a5374 17 Motor_CALIB
garphil 1:ab4c9a0a5374 18 } MotorState = Motor_IDLE;
garphil 1:ab4c9a0a5374 19
garphil 1:ab4c9a0a5374 20 enum MotorCommandList { // Define Motor State Machine Commands
garphil 1:ab4c9a0a5374 21 k_nop = 0,
garphil 1:ab4c9a0a5374 22 k_wire,
garphil 1:ab4c9a0a5374 23 k_pause,
garphil 1:ab4c9a0a5374 24 k_restart,
garphil 1:ab4c9a0a5374 25 k_stop,
garphil 1:ab4c9a0a5374 26 k_zero
garphil 1:ab4c9a0a5374 27 } MotorCommand;
garphil 1:ab4c9a0a5374 28
garphil 1:ab4c9a0a5374 29 enum MotorDirectionList { // Define Motor Clockwise or Anticlockwise
garphil 1:ab4c9a0a5374 30 d_clock = 0,
garphil 1:ab4c9a0a5374 31 d_anti
garphil 1:ab4c9a0a5374 32 } MotorDir;
garphil 1:ab4c9a0a5374 33
garphil 1:ab4c9a0a5374 34 // --- Sound ---
garphil 1:ab4c9a0a5374 35 char *song_happy_birthday = "Happy Birthday Song:d=4,o=5,b=125:16c,32p,32c,32p,8d,32p,8c,32p,8f,32p,e,16p,16c,32p,32c,32p,8d,32p,8c,32p,8g,32p,f,8p,16c,32p,32c,32p,8c6,32p,8a,32p,8f,32p,8e,32p,8d,32p,16a#,32p,32a#,32p,8a,32p,8f,32p,8g,32p,f";
garphil 1:ab4c9a0a5374 36 char *song_greensleaves = "Greensleaves:d=4,o=5,b=140:g,2a#,c6,d.6,8d#6,d6,2c6,a,f.,8g,a,2a#,g,g.,8f,g,2a,f,2d,g,2a#,c6,d.6,8e6,d6,2c6,a,f.,8g,a,a#.,8a,g,f#.,8e,f#,2g";
garphil 1:ab4c9a0a5374 37 char *song_lightmyfire = "LightMyFire:d=4,o=5,b=140:8b,16g,16a,8b,8d6,8c6,8b,8a,8g,8a,16f,16a,8c6,8f6,16d6,16c6,16a#,16g,8g#,8g,8g#,16g,16a,8b,8c#6,16b,16a,16g,16f,8e,8f,1a,a";
garphil 1:ab4c9a0a5374 38 char *song_xfile = "Xfiles:d=4,o=5,b=140:e,b,a,b,d6,2b.";
garphil 1:ab4c9a0a5374 39 char *song_christmas ="Christmas:d=4,o=5,b=100:f#,g#,2a#,2a#,d#.,8f,f,f,2f#,2d#,2f#.6,f#,#g,8g#,g#,8a#,b,8c#,c#,2c#,8d#,8f.,8f#.,8f.,d#,f,2f#.,a#,8b.,8b.,8b.,d#,f,2c#.,a#,8b.,8b.,8b.,d#,f,f#,p,g#,g#,g#,8g#,8a#,8g#,f#.,g#,a#,p,c,c,c,8c,8c#,8c,a#.,c,c#,a#,b,a#,a,a#,b,c,";
garphil 1:ab4c9a0a5374 40
garphil 1:ab4c9a0a5374 41 // --- Define PC_8 as the output of PWM use for Tones -----
garphil 1:ab4c9a0a5374 42 Buzzer buzzer(PC_8);
garphil 0:30cb0f6dad87 43
garphil 1:ab4c9a0a5374 44 Music* pMusic=0; //the song
garphil 1:ab4c9a0a5374 45 Note la("A#4",50); //the sound
garphil 1:ab4c9a0a5374 46
garphil 1:ab4c9a0a5374 47 // --- Define the Foor PINs used for Motor drive -----
garphil 1:ab4c9a0a5374 48 DigitalOut MPh3(PA_7);
garphil 1:ab4c9a0a5374 49 DigitalOut MPh2(PB_6);
garphil 1:ab4c9a0a5374 50 DigitalOut MPh1(PC_7);
garphil 1:ab4c9a0a5374 51 DigitalOut MPh0(PA_9);
garphil 1:ab4c9a0a5374 52 // --- Motor Variable
garphil 1:ab4c9a0a5374 53 int MotorIndex = 0;
garphil 1:ab4c9a0a5374 54 // --- Motor Routine
garphil 1:ab4c9a0a5374 55 void StopMotor() // --- Stop Motor
garphil 1:ab4c9a0a5374 56 {
garphil 1:ab4c9a0a5374 57 MPh0 = 0; MPh1 = 0; MPh2 = 0; MPh3 = 0;
garphil 1:ab4c9a0a5374 58 MotorIndex = 0;
garphil 1:ab4c9a0a5374 59 }
garphil 1:ab4c9a0a5374 60 void StartMotor()
garphil 1:ab4c9a0a5374 61 {
garphil 1:ab4c9a0a5374 62 MotorIndex = 0;
garphil 1:ab4c9a0a5374 63 MPh0 = 1; MPh1 = 0; MPh2 = 0; MPh3 = 0;
garphil 1:ab4c9a0a5374 64 }
garphil 1:ab4c9a0a5374 65 void RightMotor() // Move the Motor one step Right
garphil 1:ab4c9a0a5374 66 {
garphil 1:ab4c9a0a5374 67 const int RPh0[4] = {0, 1, 0, 0};
garphil 1:ab4c9a0a5374 68 const int RPh1[4] = {0, 0, 1, 0};
garphil 1:ab4c9a0a5374 69 const int RPh2[4] = {0, 0, 0, 1};
garphil 1:ab4c9a0a5374 70 const int RPh3[4] = {1, 0, 0, 0};
garphil 1:ab4c9a0a5374 71 MPh0 = RPh0[MotorIndex]; MPh1 = RPh1[MotorIndex]; MPh2 = RPh2[MotorIndex]; MPh3 = RPh3[MotorIndex];
garphil 1:ab4c9a0a5374 72 if (MotorIndex<3) MotorIndex++;
garphil 1:ab4c9a0a5374 73 else MotorIndex = 0;
garphil 1:ab4c9a0a5374 74 }
garphil 1:ab4c9a0a5374 75 void LeftMotor() // Move the Motor one step Right
garphil 1:ab4c9a0a5374 76 {
garphil 1:ab4c9a0a5374 77 const int LPh0[4] = {0, 0, 1, 0};
garphil 1:ab4c9a0a5374 78 const int LPh1[4] = {0, 1, 0, 0};
garphil 1:ab4c9a0a5374 79 const int LPh2[4] = {1, 0, 0, 0};
garphil 1:ab4c9a0a5374 80 const int LPh3[4] = {0, 0, 0, 1};
garphil 1:ab4c9a0a5374 81 MPh0 = LPh0[MotorIndex]; MPh1 = LPh1[MotorIndex]; MPh2 = LPh2[MotorIndex]; MPh3 = LPh3[MotorIndex];
garphil 1:ab4c9a0a5374 82 if (MotorIndex<3) MotorIndex++;
garphil 1:ab4c9a0a5374 83 else MotorIndex = 0;
garphil 1:ab4c9a0a5374 84 }
garphil 1:ab4c9a0a5374 85
garphil 1:ab4c9a0a5374 86 void RunMotor() // Move the Motor in the user direction
garphil 1:ab4c9a0a5374 87 {
garphil 1:ab4c9a0a5374 88 if (MotorDir==d_clock) RightMotor();
garphil 1:ab4c9a0a5374 89 else LeftMotor();
garphil 1:ab4c9a0a5374 90 }
garphil 0:30cb0f6dad87 91
garphil 1:ab4c9a0a5374 92 void ProcessMotorStateMachine()
garphil 1:ab4c9a0a5374 93 {
garphil 1:ab4c9a0a5374 94 if (MotorState==Motor_IDLE) {
garphil 1:ab4c9a0a5374 95 uint32_t led = 0;
garphil 1:ab4c9a0a5374 96 if (MotorCommand == k_wire) {
garphil 1:ab4c9a0a5374 97 // Start the Wiring
garphil 1:ab4c9a0a5374 98 StartMotor();
garphil 1:ab4c9a0a5374 99 led = 1;
garphil 1:ab4c9a0a5374 100 MotorState = Motor_RUN;
garphil 1:ab4c9a0a5374 101 }
garphil 1:ab4c9a0a5374 102 else if (MotorCommand == k_zero) {
garphil 1:ab4c9a0a5374 103 // Start zeroing the Motor
garphil 1:ab4c9a0a5374 104 StartMotor();
garphil 1:ab4c9a0a5374 105 led = 1;
garphil 1:ab4c9a0a5374 106 MotorState = Motor_ZERO;
garphil 1:ab4c9a0a5374 107 }
garphil 1:ab4c9a0a5374 108 MotorCommand = k_nop;
garphil 1:ab4c9a0a5374 109 myled = led; // LED is on when motor in use
garphil 1:ab4c9a0a5374 110 }
garphil 1:ab4c9a0a5374 111 else if (MotorState==Motor_RUN) {
garphil 1:ab4c9a0a5374 112 // Action always performed in that state
garphil 1:ab4c9a0a5374 113 if (NumSteps>0) {
garphil 1:ab4c9a0a5374 114 RunMotor();
garphil 1:ab4c9a0a5374 115 NumSteps--;
garphil 1:ab4c9a0a5374 116 }
garphil 1:ab4c9a0a5374 117 // Check next state
garphil 1:ab4c9a0a5374 118 if (MotorCommand == k_pause) {
garphil 1:ab4c9a0a5374 119 MotorState = Motor_PAUSE;
garphil 1:ab4c9a0a5374 120 }
garphil 1:ab4c9a0a5374 121 else if ((MotorCommand == k_stop)||(NumSteps<=0)) {
garphil 1:ab4c9a0a5374 122 StopMotor();
garphil 1:ab4c9a0a5374 123 MotorState = Motor_IDLE;
garphil 1:ab4c9a0a5374 124 }
garphil 1:ab4c9a0a5374 125 MotorCommand = k_nop;
garphil 1:ab4c9a0a5374 126 }
garphil 1:ab4c9a0a5374 127 else if (MotorState==Motor_PAUSE) {
garphil 1:ab4c9a0a5374 128 if (MotorCommand == k_stop) {
garphil 1:ab4c9a0a5374 129 StopMotor();
garphil 1:ab4c9a0a5374 130 NumSteps=0;
garphil 1:ab4c9a0a5374 131 MotorState = Motor_IDLE;
garphil 1:ab4c9a0a5374 132 }
garphil 1:ab4c9a0a5374 133 else if (MotorCommand == k_restart) {
garphil 1:ab4c9a0a5374 134 MotorState = Motor_RUN;
garphil 1:ab4c9a0a5374 135 }
garphil 1:ab4c9a0a5374 136 MotorCommand = k_nop;
garphil 1:ab4c9a0a5374 137 }
garphil 1:ab4c9a0a5374 138 else if (MotorState==Motor_ZERO) {
garphil 1:ab4c9a0a5374 139 MotorCommand = k_nop;
garphil 1:ab4c9a0a5374 140 }
garphil 1:ab4c9a0a5374 141 }
garphil 0:30cb0f6dad87 142
garphil 1:ab4c9a0a5374 143 void TestMotor() // Just to check that it make a full taurn back and forth
garphil 1:ab4c9a0a5374 144 {
garphil 1:ab4c9a0a5374 145 int i;
garphil 1:ab4c9a0a5374 146 StartMotor();
garphil 1:ab4c9a0a5374 147 for (i=0; i<MotorFullTurn; i++) {
garphil 1:ab4c9a0a5374 148 wait(0.005);
garphil 1:ab4c9a0a5374 149 RightMotor();
garphil 1:ab4c9a0a5374 150 }
garphil 1:ab4c9a0a5374 151 wait(0.5);
garphil 1:ab4c9a0a5374 152 for (i=0; i<MotorFullTurn; i++) {
garphil 1:ab4c9a0a5374 153 wait(0.005);
garphil 1:ab4c9a0a5374 154 LeftMotor();
garphil 1:ab4c9a0a5374 155 }
garphil 1:ab4c9a0a5374 156 StopMotor();
garphil 1:ab4c9a0a5374 157 }
garphil 1:ab4c9a0a5374 158 void help() // Display list of Commands
garphil 1:ab4c9a0a5374 159 {
garphil 1:ab4c9a0a5374 160 DEBUG("List of commands:\n\r");
garphil 1:ab4c9a0a5374 161 DEBUG(" h --> Help, display list of cammands\n\r");
garphil 1:ab4c9a0a5374 162 DEBUG(" z --> Go to motor zero\n\r");
garphil 1:ab4c9a0a5374 163 DEBUG(" k --> Calibrate motor\n\r");
garphil 1:ab4c9a0a5374 164 DEBUG(" n dddd --> define Number of coils (default=100)\n\r");
garphil 1:ab4c9a0a5374 165 DEBUG(" c --> define Clockwise (default)\n\r");
garphil 1:ab4c9a0a5374 166 DEBUG(" a --> define Anti-clockwise\n\r");
garphil 1:ab4c9a0a5374 167 DEBUG(" m --> Memorise configuration\n\r");
garphil 1:ab4c9a0a5374 168 DEBUG(" l --> List current configuration\n\r");
garphil 1:ab4c9a0a5374 169 DEBUG(" w --> start Wiring the coils\n\r");
garphil 1:ab4c9a0a5374 170 DEBUG(" p --> Pause wiring\n\r");
garphil 1:ab4c9a0a5374 171 DEBUG(" r --> Resume wiring\n\r");
garphil 1:ab4c9a0a5374 172 DEBUG(" s --> Stop (abort) wiring\n\r");
garphil 1:ab4c9a0a5374 173 DEBUG(" [space] --> print remaining Motor steps\n\r");
garphil 1:ab4c9a0a5374 174 }
garphil 1:ab4c9a0a5374 175
garphil 1:ab4c9a0a5374 176 void end_wiring() // Display message and Play a song when wirring is completed
garphil 1:ab4c9a0a5374 177 {
garphil 1:ab4c9a0a5374 178 DEBUG("--- SUCCESS: Coils wiring completed ---\n\r");
garphil 1:ab4c9a0a5374 179 // Play a single Song
garphil 1:ab4c9a0a5374 180 pMusic= new Music(song_lightmyfire);
garphil 1:ab4c9a0a5374 181 pMusic->play(&buzzer);
garphil 1:ab4c9a0a5374 182 buzzer.tone(&la);
garphil 1:ab4c9a0a5374 183 delete(pMusic);
garphil 0:30cb0f6dad87 184 }
garphil 0:30cb0f6dad87 185
garphil 0:30cb0f6dad87 186 int main() {
garphil 1:ab4c9a0a5374 187 myled = 1; // To see something is alive
garphil 1:ab4c9a0a5374 188 DEBUG("\n\n\r");
garphil 1:ab4c9a0a5374 189 DEBUG("------------------------------------------\n\r");
garphil 1:ab4c9a0a5374 190 DEBUG("----- Wire WINDER (fbd38) version 1.0 ----\n\r");
garphil 1:ab4c9a0a5374 191 DEBUG("------------------------------------------\n\r");
garphil 1:ab4c9a0a5374 192 help();
garphil 1:ab4c9a0a5374 193 DEBUG("------------------------------------------\n\r");
garphil 1:ab4c9a0a5374 194 wait(5); // Some delay
garphil 1:ab4c9a0a5374 195 myled = 0; // Real stuff starts here
garphil 1:ab4c9a0a5374 196 //
garphil 1:ab4c9a0a5374 197 // Connect Interrupt routine in which the motor and all the state machine is performed
garphil 1:ab4c9a0a5374 198 //
garphil 1:ab4c9a0a5374 199 MotorDir = d_clock; // Default direction is clockwise
garphil 1:ab4c9a0a5374 200 MotorState = Motor_IDLE; // Default state is IDLE
garphil 1:ab4c9a0a5374 201 MotorCommand = k_nop; // Default command is NOP
garphil 1:ab4c9a0a5374 202 MotorStepTime = 10000; // value in micro second for one step
garphil 1:ab4c9a0a5374 203 MotorFullTurn = 2140; // Initial Calibration
garphil 1:ab4c9a0a5374 204 NumSteps = 0; // Default
garphil 1:ab4c9a0a5374 205 MotorSystemTick.attach_us(&ProcessMotorStateMachine, MotorStepTime);
garphil 1:ab4c9a0a5374 206 //
garphil 1:ab4c9a0a5374 207 while(1) {
garphil 1:ab4c9a0a5374 208 char command; // Command to execute
garphil 1:ab4c9a0a5374 209 uint32_t TimeToRunSec, TimeToRunMin;
garphil 1:ab4c9a0a5374 210 DEBUG(">> ");
garphil 1:ab4c9a0a5374 211 command = pc_uart.getc();
garphil 1:ab4c9a0a5374 212 DEBUG("%c", command);
garphil 1:ab4c9a0a5374 213 switch (command) {
garphil 1:ab4c9a0a5374 214 case 'h': help(); break;
garphil 1:ab4c9a0a5374 215 case 'z': MotorCommand = k_zero; break;
garphil 1:ab4c9a0a5374 216 case 'k': TestMotor(); break;
garphil 1:ab4c9a0a5374 217 case 'n':
garphil 1:ab4c9a0a5374 218 pc_uart.scanf("%d", &NumWires);
garphil 1:ab4c9a0a5374 219 NumSteps = NumWires*MotorFullTurn;
garphil 1:ab4c9a0a5374 220 TimeToRunSec = (NumSteps * (MotorStepTime / 1000))/1000;
garphil 1:ab4c9a0a5374 221 TimeToRunMin = TimeToRunSec / 60;
garphil 1:ab4c9a0a5374 222 TimeToRunSec %= 60;
garphil 1:ab4c9a0a5374 223 DEBUG("%d --> Step = %d; Time = %d,%2d (min, sec)\n\r", NumWires, NumSteps, TimeToRunMin, TimeToRunSec);
garphil 1:ab4c9a0a5374 224 break;
garphil 1:ab4c9a0a5374 225 case 'c': MotorDir = d_clock; break;
garphil 1:ab4c9a0a5374 226 case 'a': MotorDir = d_anti; break;
garphil 1:ab4c9a0a5374 227 case 'm': DEBUG(" [ not ready yet ]\n\r"); break;
garphil 1:ab4c9a0a5374 228 case 'l': DEBUG(" [ not ready yet ]\n\r"); break;
garphil 1:ab4c9a0a5374 229 case 'w': DEBUG(" -- Starting --\n\r"); MotorCommand = k_wire; break;
garphil 1:ab4c9a0a5374 230 case 'p': DEBUG(" -- Pause --\n\r"); MotorCommand = k_pause; break;
garphil 1:ab4c9a0a5374 231 case 'r': DEBUG(" -- Re-Start --\n\r"); MotorCommand = k_restart; break;
garphil 1:ab4c9a0a5374 232 case 's': DEBUG(" -- Stop --\n\r"); MotorCommand = k_stop; break;
garphil 1:ab4c9a0a5374 233 case ' ':
garphil 1:ab4c9a0a5374 234 TimeToRunSec = (NumSteps * (MotorStepTime / 1000))/1000;
garphil 1:ab4c9a0a5374 235 TimeToRunMin = TimeToRunSec / 60;
garphil 1:ab4c9a0a5374 236 TimeToRunSec %= 60;
garphil 1:ab4c9a0a5374 237 DEBUG(" Step to run: %d; Time %d,%2d (min, sec)\n\r", NumSteps, TimeToRunMin, TimeToRunSec);
garphil 1:ab4c9a0a5374 238 break;
garphil 1:ab4c9a0a5374 239 default : DEBUG("invalid command; use: 'h' for help()");
garphil 1:ab4c9a0a5374 240 }
garphil 0:30cb0f6dad87 241 }
garphil 1:ab4c9a0a5374 242 }