Callum and Adel's changes on 12/02/19

Dependencies:   Crypto

Revision:
50:d1b983a0dd6f
Parent:
49:ae8dedfe2d0f
Child:
51:c03f63c6f930
--- a/main.cpp	Fri Mar 22 16:50:54 2019 +0000
+++ b/main.cpp	Fri Mar 22 19:05:40 2019 +0000
@@ -111,7 +111,7 @@
 
         volatile int8_t     _modeBitField;                              // 0,0,0,... <=> Melody,Torque,Rotation,Velocity
         const    uint8_t    _MAXCMDLENGTH;                              // 
-        volatile uint8_t    _inCharIndex, _cmdIndex,
+        volatile uint8_t    _inCharIndex, _cmdIndex, _noteRep,
                             _noteDur[MAXCMDLENGTH_HALF],_noteLen;       // Array of note durations
         volatile uint32_t   _motorTorque;                               // Motor Toque
         volatile uint64_t   _newKey;                                    // hash key
@@ -272,29 +272,29 @@
                 }
 
             if (len>0) {                                                // Parse the input only if # found
-                uint8_t newLen = 2*(len+1)+1;
-                bool isChar = true;
-                char formatSpec[newLen];
+                uint8_t specLen = 2*(len+1) +1;                         // Add extra character for number of repeats, and +1 for the letter T
+                bool isChar = true;                                     // After 'T' first is character note
+                char formatSpec[specLen];
                 formatSpec[0]='T';
-                for (int i = 1; i < newLen; i=i+2) {                    // Create a format spec based on length of input
+                for (int i = 1; i < specLen; i=i+2) {                    // Create a format spec based on length of input
                     formatSpec[i] = '%';
                     isChar ? formatSpec[i+1] = 'c' : \
                              formatSpec[i+1] = 'u' ;
                     isChar = !isChar;
                 }
 
-                formatSpec[newLen] = '\0';
+                formatSpec[specLen] = '\0';
                 sprintf(formatSpec, "%s", formatSpec);                  // Set string format correctly
                 // _pc.printf("%s\n", formatSpec );
                 sscanf(_newCmd, formatSpec, &_notes[0], &_noteDur[0],
-                                           &_notes[1], &_noteDur[1],
-                                           &_notes[2], &_noteDur[2],
-                                           &_notes[3], &_noteDur[3],
-                                           &_notes[4], &_noteDur[4],
-                                           &_notes[5], &_noteDur[5],
-                                           &_notes[6], &_noteDur[6],
-                                           &_notes[7], &_noteDur[7],
-                                           &_notes[8], &_noteDur[8]); 
+                                            &_notes[1], &_noteDur[1],
+                                            &_notes[2], &_noteDur[2],
+                                            &_notes[3], &_noteDur[3],
+                                            &_notes[4], &_noteDur[4],
+                                            &_notes[5], &_noteDur[5],
+                                            &_notes[6], &_noteDur[6],
+                                            &_notes[7], &_noteDur[7],
+                                            &_notes[8], &_noteDur[8]); 
                 
                          
                 // Update _newCmd for putMessage print
@@ -307,7 +307,9 @@
                                             _notes[6],  _noteDur[6],\
                                             _notes[7],  _noteDur[7],\
                                             _notes[8],  _noteDur[8]);
-                _noteLen = len;
+                _noteLen = (len-1)/2;
+                _modeBitField = 0x08;
+                _noteRep = _noteDur[(len-1)/2];
                 return true;
             }
             else {
@@ -464,7 +466,7 @@
             
             _dutyC = 0.8;                                               // Default a lower duty cycle
             pwmCtrl.period_us((uint32_t)mtrPeriod);
-            pwmCtrl.pulsewidth_us((uint32_t)mtrPeriod*_dutyC);
+            pwmCtrl.pulsewidth_us((uint32_t)(mtrPeriod*_dutyC));
 
              _pComm = comm;
             _RUN = true;
@@ -568,6 +570,17 @@
                              old_err = 0.0f,
                              err_diff;
 
+
+            enum { // To nearest Hz
+                    NOTE_C = 261, // C4
+                    NOTE_D = 293, // D4
+                    NOTE_E = 330, // E4
+                    NOTE_F = 349, // F4
+                    NOTE_G = 392, // G4
+                    NOTE_A = 440, // A4
+                    NOTE_B = 494 // B4
+            };
+
             m_timer.start();
 
             while (_RUN) {
@@ -631,6 +644,74 @@
                         oldTorque = torque;
                     }
                 }
+                else if (cpyModeBitfield & 0x08) {                      // If it is in Melody mode
+                    uint32_t oldMtrPeriod = mtrPeriod; // Backup of current motor period
+                    float    oldDutyC = _dutyC;        // Backup of current duty cycle
+                    uint32_t noteFreq, newDur, newPeriod =0,
+                             oldPeriod = mtrPeriod;
+
+                    Timer testTimer;
+                    testTimer.start();
+                    _pComm->_pc.printf("rep:%i, len:%i \n\r", _pComm->_noteRep, _pComm->_noteLen);
+                    for (int k = 0; k < _pComm->_noteRep; ++k) {
+                        
+                        for (int i = 0; i < _pComm->_noteLen; ++i) {
+
+                            noteFreq = 0;
+                            newDur = (uint32_t)_pComm->_noteDur[i]*1e3; // ms
+
+                            switch (_pComm->_notes[i]) {
+                                case 'C':
+                                    noteFreq = NOTE_C; 
+                                    break;
+                                case 'D':
+                                    noteFreq = NOTE_D; 
+                                    break;
+                                case 'E':
+                                    noteFreq = NOTE_E; 
+                                    break;
+                                case 'F':
+                                    noteFreq = NOTE_F; 
+                                    break;
+                                case 'G':
+                                    noteFreq = NOTE_G; 
+                                    break;
+                                case 'A':
+                                    noteFreq = NOTE_A; 
+                                    break;
+                                case 'B':
+                                    noteFreq = NOTE_B; 
+                                    break;
+                                default:
+                                    break;
+                            }
+
+                            newPeriod = (uint32_t)(1e6/(uint32_t)noteFreq); // us
+
+                            if (newPeriod>oldPeriod) {  // Change Period First
+                                _pComm->_pc.printf("Period:changed \n" );
+                                pwmCtrl.period_us(newPeriod);       //set frequency of PWM
+                                pwmCtrl.pulsewidth_us((uint32_t)(newPeriod*0.8)); 
+                            } else {                    // Change Pulse WidthFirst
+                                pwmCtrl.pulsewidth_us((uint32_t)(newPeriod*0.8)); 
+                                pwmCtrl.period_us(newPeriod);       //set frequency of PWM
+                            }
+                            // stateUpdate();
+                            oldPeriod = newPeriod;
+                            testTimer.reset();
+                            while (testTimer.read_ms() < newDur ) {} // Do nothing 
+                            _pComm->_pc.printf("Period:%d Dur:%d \n",newPeriod, newDur );
+                        }
+
+                     _pComm->_modeBitField = 0x04; // stop melody mode
+
+                    }
+                    // After playing notes, go back to the old speed
+                    torque = (int32_t)_pComm->_motorTorque;
+                    pwmCtrl.pulsewidth_us((uint32_t)(torque*0.8));
+                    // And reset the motor period and duty cycle
+
+                }
                 else{
                     torque = _MAXPWM_PRD * 0.5;                         // Run at 50% duty cycle if argument not properly defined