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.
Fork of Blue_Board_Ticker by
main.cpp
- Committer:
- vicyap
- Date:
- 2016-04-15
- Revision:
- 21:2bf65c29a3c6
- Parent:
- 20:029a58eb24ab
- Child:
- 22:72905102b50d
File content as of revision 21:2bf65c29a3c6:
#include "mbed.h" PwmOut phaseA(PA_8); //Out1, Green DigitalOut phaseAEN(PC_10); PwmOut phaseB(PA_9); //Out2, Blue DigitalOut phaseBEN(PC_11); PwmOut phaseC(PA_10); //Out3, White DigitalOut phaseCEN(PC_12); AnalogIn pot(PB_1); InterruptIn button(USER_BUTTON); DigitalOut redLed(PB_2); DigitalOut led(LED1); InterruptIn hallA(PA_15); //H1, Green InterruptIn hallB(PB_3); //H2, Blue InterruptIn hallC(PB_10); //H3, White Ticker rpmInterrupt; Ticker spinTicker; int revCount = 0; int rpmPrintFlag = 0; int currentRPM; int ADCCountMax = 1000; // tune for responsiveness vs. stability, higher value -> less responsive -> more stable float pwmMax = 0.9; // tune for max pwmDuty. higher value -> more power available float pwmDuty; int stall = 0; int reverse = 0; int spinTickerCounter = 0; int spinTickerPeriod_us = 50; // tune for how often hall sensors are checked int ticksPerHall = 0; int prevHallState = 0; float reverseThreshold = 0.4f; // tune for minimum duty cycle to allow reverse int pole_pairs = 2; // tune for proper mech rpm calculation void init() { phaseA.period_us(50); phaseB.period_us(50); phaseC.period_us(50); phaseA.write(0); phaseB.write(0); phaseC.write(0); phaseAEN = 0; phaseBEN = 0; phaseCEN = 0; // init the prevHallState int h1 = hallA.read(); int h2 = hallB.read(); int h3 = hallC.read(); prevHallState = (h1 << 2) + (h2 << 1) + h3; } void rpmCalc() { currentRPM = revCount * 60; // 60 seconds in 1 minute currentRPM /= pole_pairs; // account for elec vs mech rpm if (reverse == 1) { currentRPM = -currentRPM; // indicate a reverse direction } revCount = 0; rpmPrintFlag = 1; } //original names: CBA CBA, new names: BAC BAC void Output_ANull_BLow_CHigh() //state1, A0 B- C+ { phaseA.write(0); phaseB.write(0); phaseC.write(pwmDuty); phaseAEN = 0; phaseBEN = 1; phaseCEN = 1; } void Output_AHigh_BLow_CNull() //state2, A+ B- C0 { phaseA.write(pwmDuty); phaseB.write(0); phaseC.write(0); phaseAEN = 1; phaseBEN = 1; phaseCEN = 0; } void Output_AHigh_BNull_CLow() //state3, A+ B0 C- { phaseA.write(pwmDuty); phaseB.write(0); phaseC.write(0); phaseAEN = 1; phaseBEN = 0; phaseCEN = 1; } void Output_ANull_BHigh_CLow() //state4, A0 B+ C- { phaseA.write(0); phaseB.write(pwmDuty); phaseC.write(0); phaseAEN = 0; phaseBEN = 1; phaseCEN = 1; } void Output_ALow_BHigh_CNull() //state5, A- B+ C0 { phaseA.write(0); phaseB.write(pwmDuty); phaseC.write(0); phaseAEN = 1; phaseCEN = 0; phaseBEN = 1; } void Output_ALow_BNull_CHigh() //state6, A- B0 C+ { phaseAEN = 1; phaseBEN = 0; phaseCEN = 1; phaseA.write(0); phaseB.write(0); phaseC.write(pwmDuty); } void toggleRedLed() { redLed = !redLed; } void SixStepNext() { int h1 = hallA.read(); int h2 = hallB.read(); int h3 = hallC.read(); //check where we start int currentHallState = (h1 << 2) + (h2 << 1) + h3; if (currentHallState != prevHallState) { ticksPerHall = spinTickerCounter; spinTickerCounter = 0; // reset the number of ticks per hall sensor change if (prevHallState == 1) // arbitrarily choose state 1 { revCount += 1; } } prevHallState = currentHallState; spinTickerCounter += 1; // count the number of times spinTicker runs per hall sensor if (reverse == 0) { if(h1 == 0 && h2 == 1 && h3 == 1) { //state1 Output_AHigh_BLow_CNull(); } else if(h1 == 0 && h2 == 0 && h3 == 1) { //state2 Output_AHigh_BNull_CLow(); } else if(h1 == 1 && h2 == 0 && h3 == 1) { //state3 Output_ANull_BHigh_CLow(); } else if(h1 == 1 && h2 == 0 && h3 == 0) { //state4 Output_ALow_BHigh_CNull(); } else if(h1 == 1 && h2 == 1 && h3 == 0) { //state5 Output_ALow_BNull_CHigh(); } else if (h1 == 0 && h2 == 1 && h3 == 0) { //state6 Output_ANull_BLow_CHigh(); } } else if (reverse == 1) // to go in reverse, shift the mappings by 180 degrees { if(h1 == 0 && h2 == 1 && h3 == 1) { //state1 Output_ALow_BHigh_CNull(); } else if(h1 == 0 && h2 == 0 && h3 == 1) { //state2 Output_ALow_BNull_CHigh(); } else if(h1 == 1 && h2 == 0 && h3 == 1) { //state3 Output_ANull_BLow_CHigh(); } else if(h1 == 1 && h2 == 0 && h3 == 0) { //state4 Output_AHigh_BLow_CNull(); } else if(h1 == 1 && h2 == 1 && h3 == 0) { //state5 Output_AHigh_BNull_CLow(); } else if (h1 == 0 && h2 == 1 && h3 == 0) { //state6 Output_ANull_BHigh_CLow(); } } toggleRedLed(); } void user_button_callback() { if(stall == 0) { stall = 1; } else { if (pwmDuty < reverseThreshold) { reverse = reverse ^ 1; } } } int main() { //wait until button push to start rpmInterrupt.attach(&rpmCalc, 1); button.rise(&user_button_callback); while(stall == 0) { led = !led; wait(1); } init(); spinTicker.attach_us(&SixStepNext, spinTickerPeriod_us); float ADCSum = 0; int ADCCount = 0; while(1) { led = !led; if(ADCCount == ADCCountMax) { ADCSum = ADCSum - (ADCSum / ADCCountMax); ADCSum += pot.read(); pwmDuty = (ADCSum/ADCCountMax) * pwmMax; } else { ADCSum += pot.read(); ADCCount++; } if(rpmPrintFlag == 1) { printf("%d rpm; %f duty; reverse: %d; ticksPerHall = %d\r\n", currentRPM, pwmDuty, reverse, ticksPerHall); rpmPrintFlag = 0; } } }