💾
EC
  • Introduction
  • EC Course
    • Syllabus
    • Preparation for EC
    • Tutorial
      • Tutorial: arduino-stm32
        • Tutorial: arduino-stm32 Installation
        • Tutorial: arduino-stm32 Part1
        • Tutorial: arduino-stm32 Part2
      • Tutorial: MDK uVision
        • Tutorial: Installing MDK uVision
        • Tutorial: Create a Project with uVision
        • Tutorial: Adding library header in uVision
        • Tutorial: Re-using Project Configuration
        • Debugging in uVision
      • Tutorial: PlatformIO in CLion
      • Tutorial: PlatformIO in VSCode
      • Tutorial: Repository Management
      • Tutorial: Managing library header files
      • Tutorial: PinName Configuration
      • Tutorial: Bitwise Macro
      • Tutorial: Custom initialization
      • Tutorial: Documentation
      • Tutorial: Creating Application API
      • Tutorial: 7-Segment Display
      • Tutorial: DC motor driver connection
      • Tutorial: USART with TeraTerm
      • Tutorial: Finite State Machine programming
      • Tutorial: Bluetooth
      • Tutorial: Zigbee with Nucleo board
    • LAB
      • LAB Report Template
      • LAB: Smart mini-fan with STM32-duino
      • LAB: Portable Fan with mbed
      • LAB: GPIO Digital InOut
      • LAB: GPIO Digital InOut 7-segment
      • LAB: EXTI & SysTick
      • LAB: Timer & PWM
      • LAB: Stepper Motor
      • LAB: Input Capture - Ultrasonic
      • LAB: USART - LED, Bluetooth
      • LAB: ADC - IR reflective sensor
      • LAB: Line Tracing RC Car
    • Sample code
      • Code Templates
    • Hardware
      • Nucleo-F411RE
      • LAB Hardware
        • Electronic Chips
        • HUINS Embedded Kit
    • Projects
      • Line Tracing Car Project
      • Design Project
        • Past Projects
      • Project Grading Criteria
    • Study Resource for MCU
      • Hexa-Decimal Table
      • Bitwise Op for Register
      • System Clock
      • Timer
      • USART
      • ADC
  • STM32 M4 Programming
    • Documentation
      • C++ API Docs
    • Firmware Library
      • PinName Configuration
      • GPIO Digital
      • RCC
      • EXTI_SysTick
      • TIMER
      • USART
    • Troubleshooting
    • mbed for STM32
      • Tutorial: mbed-Part 1
      • Tutorial: mbed - Part 2
      • Tutorial: mbed - Part 3
      • Using mbed API on uVision
    • mbed OS
  • Other Programming
    • Arduino
    • Socket Programming
      • Window Socket Programming
      • Arduino WiFi
    • Cube-MX
    • Github
    • Markdown
      • Example: API documentation
    • MATLAB
  • C Programming
    • C-Programming Lessons
      • Installing Visual Studio Community
        • Visual Studio Community 2022
      • Installing VS Code(Mac/Linux)
      • Creating Header Lib
      • Pointer
      • Array
      • 2D Array
      • Structure
      • Dynamic Alloc
      • Bitwise Operation
  • Numerical Programming
    • Syllabus
    • Preparation for NP
    • Math Review
    • Tutorial
      • TA Session Video
      • Tutorial: NP Library Header Files
      • Tutorial - Sine Taylor
      • Tutorial: Passing a Function, Function callback
      • Tutorial: Nonlinear solver
      • Tutorial: Differentiation
      • Tutorial: Integration
      • Tutorial: Matrix Structure
      • Tutorial: Eigenvalue problem
      • Tutorial: ODE-IVP
      • Tutorial: Curve Fitting
      • Tutorial: Create Github Repos of NP lib
      • Tutorial: Version Control in Github
      • Tutorial: Documentation with Markdown
      • Exercise: Version Control and Documentation
    • Example: MATLAB
    • Example: NP Library
    • Assignment
      • Assignment Factorial and Power
      • Assignment: Version Control and Documentation
    • Problem Bank
Powered by GitBook
On this page
  • Problem
  • State Diagram
  • Method 1 (Recommended)
  • Method 2

Was this helpful?

  1. EC Course
  2. LAB

LAB: Portable Fan with mbed

PreviousLAB: Smart mini-fan with STM32-duinoNextLAB: GPIO Digital InOut

Last updated 2 years ago

Was this helpful?

Problem

An automatic mini-fan that runs only when the face is near the fan

  1. As the button B1 is pressed, change the DC motor velocity

  • The mode is OFF(0%), MID(50%), HIGH(100%)

  • As the B1 is pressed, it should toggle from OFF mode to HIGH mode and so on

2. Automatically ReStart and Stop the DC motor when the mode is

  • CONT: The distance is within about 50mm

  • PAUSE: The distance is beyond about 50mm

State Diagram

Method 1 (Recommended)

Using structure variable for state definition

// created by Y.K Kim


#include "mbed.h"

// State Definition
#define OFF 0
#define MID 1
#define HIGH 2

// State Input Definition
#define IN_CONT 1
#define IN_PAUSE 0

typedef struct {
    uint32_t out;
    uint32_t next[3];
} State_t;

State_t FSM[4] = {
 {0, {OFF,MID}},
 {5, {MID,HIGH}},
 {10, {HIGH,OFF}}
};



int state = OFF;
int stateInput = IN_CONT;
int stTime = 0;
int endTime = 0;
int bNextState = 0;
int bPressed=0;


InterruptIn button(USER_BUTTON);
DigitalOut  led(LED1);
PwmOut      pwm1(D11);
Serial      pc(USBTX, USBRX, 9600);
PwmOut      trig(D10); // Trigger í•€
InterruptIn echo(D7);  // Echo í•€
Timer       tim;




void nextState(int _state, int input) {
    double pwm;
    state=_state;
    
    if (bPressed)    
        state = FSM[_state].next[stateInput];    // Next State
    bPressed=0;
    
    if (stateInput == IN_CONT)
        pwm = FSM[state].out;
    else
        pwm = 0;
        
    pwm1.pulsewidth_ms(pwm);

    if (state == OFF)
        led = 0;
    else
        led = 1;

    
}

void pressed()
{   
    bPressed=1;
    nextState(state, stateInput);
    
}

void setup(void)
{
    pwm1.period_ms(10);
    trig.period_ms(60);     // period      = 60ms
    trig.pulsewidth_us(10); // pulse-width = 10us
}



void rising() {
    stTime = tim.read_us();
}

void falling() {
    endTime = tim.read_us();
}



int main()
{
    int thresh = 5;
    float distance = 0;

    setup();
    // BT interrupt
    button.fall(&pressed);
    // InputCapture interrupt
    echo.rise(&rising);
    echo.fall(&falling);
    // Start time measurement
    tim.start();

    while (1) {
        // Check distance
        distance = abs((float)(endTime - stTime)) / 58; // [cm]

        if (distance > thresh) {
            if (stateInput != IN_PAUSE) bNextState = 1;
            stateInput = IN_PAUSE;
        }
        else {
            if (stateInput != IN_CONT) bNextState = 1;
            stateInput = IN_CONT;
        }

        // change state only if there is a change in the input
        //if (bNextState)  
        nextState(state,stateInput);
        bNextState = 0;
        printf("input = %d, state = %d, distance = %.2f\r\n",stateInput, state, distance);
        wait(0.1);
    }
}

Method 2

Using case switch for next state definition

// Method 1
// by Y.K Kim


#include "mbed.h"

// State Definition
#define OFF 0
#define MID 1
#define HIGH 2

// State Input Definition
#define IN_CONT 1
#define IN_PAUSE 0

int state=0;
int stateInput = 0;
int stTime = 0;
int endTime = 0;
int bNextState = 0;
int bPressed=0;

InterruptIn button(USER_BUTTON);
DigitalOut  led(LED1);
PwmOut      pwm1(D11);
Serial      pc(USBTX, USBRX, 9600);
PwmOut      trig(D10); // Trigger í•€
InterruptIn echo(D7);  // Echo í•€
Timer       tim;


// Mealy FSM
void  outputState(int _state, int input) {
    if (_state == OFF)
        led = 0;
    else
        led = 1;

    if (!input)
        pwm1.pulsewidth_ms(0);
    else
        pwm1.pulsewidth_ms(_state * 5);    
}

void nextState(int _state, int input) {
    int nextstate = 0;
    state=_state;
    
    if (bPressed){        
        switch (_state) {
            case 0:
            case 1:
                if (input)
                    nextstate = _state + 1;
                else
                    nextstate=_state;
                break;
            case 2:
                if (input)
                    nextstate = 0;
                else
                    nextstate = _state;
                break;
            }
        state = nextstate;
    }

    outputState(state, input);
    bPressed=0;
}


void pressed()
{   
   bPressed=1;
   nextState(state, stateInput);
}

void setup(void)
{
    pwm1.period_ms(10);

    trig.period_ms(60);     // period      = 60ms
    trig.pulsewidth_us(10); // pulse-width = 10us
}


void rising() {
    stTime = tim.read_us();
}

void falling() {
    endTime = tim.read_us();
}


int main()
{
    int thresh = 5;
    float distance = 0;

    setup();
    // BT interrupt
    button.fall(&pressed);  
    // InputCapture interrupt
    echo.rise(&rising);
    echo.fall(&falling);
    // Start time measurement
    tim.start();

    while (1) {     
        // Check distance
        distance = (float)(endTime - stTime) / 58; // [cm]

        if (distance > thresh){ 
            if (stateInput != IN_PAUSE) bNextState = 1;
            stateInput = IN_PAUSE;
        }
        else {          
            if (stateInput != IN_CONT) bNextState = 1;
            stateInput = IN_CONT;
        }
        
        // change state only if there is a change in the input
        if(bNextState)  nextState(state, stateInput);
        bNextState = 0;
        wait(0.1);
    }
}