💾
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
  • LAB: Smart mini-fan with STM32-duino
  • I. Introduction
  • II. Procedure
  • IV. Report & Score
  • FSM Examples
  • Example 1
  • Example 2
  • FSM Example 3

Was this helpful?

  1. EC Course
  2. LAB

LAB: Smart mini-fan with STM32-duino

LAB: Smart mini-fan with STM32-duino

I. Introduction

In this lab, you are required to create a simple program that uses arduino IDE for implementing a simple embedded digital application. Refer to online arduino references for the full list of APIs.

Hardware

NUCLEO -F401RE or NUCLEO -F411RE

Ultrasonic distance sensor(HC-SR04), DC motor (RK-280RA)

Software

Arduino IDE

II. Procedure

The program needs to run the Fan only when the distance of an object is within a certain value.

Example: An automatic mini-fan that runs only when the face is near the fan. Otherwise turns off.

  • As the button B1 is pressed, change the fan velocity. The MODE(states) are

    • MODE(state): OFF(0%), MID(50%), HIGH(100%)

  • When the object(face) is detected about 50 mm away, then it automatically pauses the fan temporarily.

    • Even the fan is temporarily paused, the MODE should be changed whenever the button B1 is pressed

  • When the object(face) is detected within 50mm, then it automatically runs the fan

    • It must run at the speed of the current MODE

  • LED(LED1): Turned OFF when MODE=OFF. Otherwise, blink the LED with 1 sec period (1s ON, 1s OFF)

  • Print the distance and PWM duty ratio in Tera-Term console (every 1 sec).

  • Must use Mealy FSM to control the mini-fan

    • Draw a FSM(finite-state-machine) table and state diagram

    • Example Table. See below for example codes

III. Configuration

Ultrasonic distance sensor

Trigger:

  • Generate a trigger pulse as PWM to the sensor

  • Pin: D10 (TIM4 CH1)

  • PWM out: 50ms period, 10us pulse-width

Echo:

  • Receive echo pulses from the ultrasonic sensor

  • Pin: D7 (Timer1 CH1)

  • Input Capture: Input mode

  • Measure the distance by calculating pulse-width of the echo pulse.

USART

  • Display measured distance in [cm] on serial monitor of Tera-Term.

  • Baudrate 9600

DC Motor

  • PWM: PWM1, set 10ms of period by default

  • Pin: D11 (Timer1 CH1N)

IV. Report & Score

You are required to write a concise lab report in 'md' format. On-Line submission.

Lab Report:

  • Write Lab Title, Date, Your name

  • Introduction

  • Draw State Table and State Diagram to explain your logic [30%]

  • Explain your source code with necessary comments [30%]

  • External circuit diagram that connects MCU pins to peripherals(sensor/actuator) [10%]

  • Demonstration Video. Include the link in the report [30%]

  • Submit in both PDF and original file (*.md etc)

FSM Examples

Example 1

INPUT:

  • X: Button Pressed {0, 1}

OUTPUT:

  • LED {ON, OFF}

STATE:

  • S0: FAN OFF State

  • S1: FAN ON State

Moore FSM Table

Mealy FSM Table

Example Code


#include <stdio.h>

// State definition
#define S0  0
#define S1  1

#define LOW  0
#define HIGH  1

unsigned char state = S0;
unsigned char nextstate = S0;
unsigned char input = LOW;
unsigned char ledOut = LOW;


typedef struct {
	unsigned int next[2];   // nextstate = FSM[state].next[input]
	unsigned int out;    // output = FSM[state].out
} State_t;

State_t FSM[2] = {
  {{S0, S1},LOW},
  {{S1, S0},HIGH}
};

int main()
{
    printf("Start\n\r");
    
    input=LOW;    
    nextstate = FSM[state].next[input];
    state=nextstate;
    ledOut = FSM[state].out;
    printf("state=%d,  ledOut=%d \n\r",state,ledOut);
    
    input=HIGH;
    nextstate = FSM[state].next[input];
    state=nextstate;
    ledOut = FSM[state].out;
    printf("state=%d,  ledOut=%d \n\r",state,ledOut);

    input=LOW;    
    nextstate = FSM[state].next[input];
    state=nextstate;
    ledOut = FSM[state].out;
    printf("state=%d,  ledOut=%d \n\r",state,ledOut);

    return 0;
}
// State definition
#define S0  0
#define S1  1

// Address number of output in array
#define LED 1

typedef struct {
	uint32_t next[2];   // nextstate = FSM[state].next[input]
	uint32_t out;    // output = FSM[state].out
} State_t;

State_t FSM[2] = {
  {{S0, S1},LOW},
  {{S1, S0},HIGH}
};

const int ledPin = 13;
const int btnPin = 3;

unsigned char state = S0;
unsigned char input = 0;
unsigned char ledOut = LOW;

void setup() {
	// initialize the LED pin as an output:
	pinMode(ledPin, OUTPUT);
		
	// initialize the pushbutton pin as an interrupt input:
	pinMode(btnPin, INPUT_PULLUP);
	attachInterrupt(digitalPinToInterrupt(btnPin), pressed, FALLING);

	Serial.begin(9600);
}

void loop() {
	// First, Update next state. Then, Output.  Repeat
	// 1. Update State <-- Next State
	nextState();

	// 2. Output of states - Logic
	stateOutput();

	digitalWrite(ledPin, ledOut);

	delay(1000);
}

void pressed() {
	input = 1;
}

void nextState() {
	state = FSM[state].next[input];
	// Intialize Button Pressed 
	input = 0;
}

void stateOutput() {
	ledOut = FSM[state].out;
}
#include <stdio.h>

// State definition
#define S0  0
#define S1  1

#define LOW  0
#define HIGH  1

unsigned char state = S0;
unsigned char nextstate = S0;
unsigned char input = LOW;
unsigned char ledOut = LOW;


// State table definition
typedef struct {
	unsigned int next[2];       // nextstate = FSM[state].next[input]
	unsigned int out[2];        // output = FSM[state].out[input]
} State_t;

State_t FSM[2] = {
  { {S0, S1},{LOW,HIGH} },
  { {S1, S0},{HIGH,LOW} }
};

int main()
{
    printf("Start\n\r");
    
    input=LOW;
    ledOut = FSM[state].out[input];
    nextstate = FSM[state].next[input];
    state=nextstate;
    printf("state=%d,  ledOut=%d \n\r",state,ledOut);
    
    input=HIGH;
    ledOut = FSM[state].out[input];
    nextstate = FSM[state].next[input];
    state=nextstate;
    printf("state=%d,  ledOut=%d \n\r",state,ledOut);
    
    input=LOW;
    ledOut = FSM[state].out[input];
    nextstate = FSM[state].next[input];
    state=nextstate;
    printf("state=%d,  ledOut=%d \n\r",state,ledOut);
    
    return 0;
}


// State definition
#define S0  0
#define S1  1

// Address number of output in array
#define PWM 0
#define LED 1

const int ledPin = 13;
const int pwmPin = 11;
const int btnPin = 3;

unsigned char state = S0;
unsigned char nextstate = S0;
unsigned char input = 0;
unsigned char ledOut = LOW;
unsigned char pwmOut = 0;

// State table definition
typedef struct {
	unsigned int next[2];       // nextstate = FSM[state].next[input]
	unsigned int out[2];        // output = FSM[state].out[input]
} State_t;

State_t FSM[2] = {
  { {S0, S1},{LOW,HIGH} },
  { {S1, S0},{HIGH,LOW} }
};

void setup() {
	// initialize the LED pin as an output:
	pinMode(ledPin, OUTPUT);

	
	// initialize the pushbutton pin as an interrupt input:
	pinMode(btnPin, INPUT_PULLUP);
	attachInterrupt(digitalPinToInterrupt(btnPin), pressed, FALLING);
}

void loop() {
	// First, Output of current State. Then Update next state. Repeat

	// 1. Output State
	stateOutput();
	digitalWrite(ledPin, ledOut);

	// 2. Update State <-- Next State
	nextState();

	delay(1000);
}


void pressed() {
	input = 1;
}

void nextState() {
	nextstate = FSM[state].next[input];
	state = nextstate;

	// Intialize Button Pressed 
	input = 0;
}

void stateOutput() {	
	ledOut = FSM[state].out[input];
}

Example 2

INPUT:

  • X: Button Pressed {0, 1}

OUTPUT:

  • VEL {0%, 100%}

  • LED {ON, OFF}

STATE:

  • S0: FAN OFF State

  • S1: FAN ON State

Mealy FSM Table

Moore FSM Table

Example Code

// State definition
#define S0  0
#define S1  1

const int ledPin = 13;
const int pwmPin = 11;
const int btnPin = 3;

unsigned char state = S0;
unsigned char nextstate = S0;
unsigned char input = 0;
unsigned char ledOut = LOW;
unsigned char pwmOut = 0;

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);

  // Initialize pwm pin as an output:
  pinMode(pwmPin, OUTPUT);
  
  // initialize the pushbutton pin as an interrupt input:
  pinMode(btnPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(btnPin), pressed, FALLING);
}

void loop() {
  // Calculate next state. then update State
  nextState();

  // Output
  analogWrite(pwmPin, pwmOut);
  digitalWrite(ledPin, ledOut);
  
  delay(1000);
}

void pressed(){
  input = 1;
}

void nextState(){
  switch(state){
    case S0:
      if (input){
        nextstate = S1;
        pwmOut = 160;
        ledOut = HIGH;
      }
      else{
        nextstate = S0;
        pwmOut = 0;
        ledOut = LOW;
      }
      break;
    case S1:
      if (input){
        nextstate = S0;
        pwmOut = 0;
        ledOut = LOW;
      }
      else {
        nextstate = S1;
        pwmOut = 160;
        ledOut = HIGH;
      }
      break;
  }

  state = nextstate;
  input = 0;
}
// State definition
#define S0  0
#define S1  1

// Address number of output in array
#define PWM 0
#define LED 1

const int ledPin = 13;
const int pwmPin = 11;
const int btnPin = 3;

unsigned char state = S0;
unsigned char nextstate = S0;
unsigned char input = 0;
unsigned char ledOut = LOW;
unsigned char pwmOut = 0;

// State table definition
typedef struct {
  uint32_t out[2][2];     // output = FSM[state].out[input][PWM or LED]
  uint32_t next[2];       // nextstate = FSM[state].next[input]
} State_t;

State_t FSM[2] = {
  { {{0  , LOW }, {160, HIGH}}, {S0, S1} },
  { {{160, HIGH}, {0  , LOW }}, {S1, S0} } 
};

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);

  // Initialize pwm pin as an output:
  pinMode(pwmPin, OUTPUT);
  
  // initialize the pushbutton pin as an interrupt input:
  pinMode(btnPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(btnPin), pressed, FALLING);
}

void loop() {
  // First, Output of current State. Then Update next state. Repeat

  // 1. Output State
  stateOutput();
  analogWrite(pwmPin, pwmOut);
  digitalWrite(ledPin, ledOut);

  // 2. Update State <-- Next State
  nextState();

  delay(1000);
}


void pressed() {
  input = 1;
}

void nextState() {
  nextstate = FSM[state].next[input];
  state = nextstate;

  // Intialize Button Pressed 
  input = 0;
}

void stateOutput() {
  pwmOut = FSM[state].out[input][PWM];
  ledOut = FSM[state].out[input][LED];
}
// State definition
#define S0  0
#define S1  1

// Address number of output in array
#define PWM 0
#define LED 1

typedef struct {
  uint32_t out[2];    // output = FSM[state].out[PWM or LED]
  uint32_t next[2];   // nextstate = FSM[state].next[input]
} State_t;

State_t FSM[2] = {
  {{0   , LOW }, {S0, S1}},
  {{160 , HIGH}, {S1, S0}}
};

const int ledPin = 13;
const int pwmPin = 11;
const int btnPin = 3;

unsigned char state = S0;
unsigned char input = 0;
unsigned char pwmOut = 0;
unsigned char ledOut = LOW;

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);

  // Initialize pwm pin as an output:
  pinMode(pwmPin, OUTPUT);
  
  // initialize the pushbutton pin as an interrupt input:
  pinMode(btnPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(btnPin), pressed, FALLING);
  
  Serial.begin(9600);
}

void loop() {
  // First, Update next state. Then, Output.  Repeat
  // 1. Update State <-- Next State
  nextState();

  // 2. Output of states
  stateOutput();

  analogWrite(pwmPin, pwmOut);
  digitalWrite(ledPin, ledOut);

  delay(1000);
}

void pressed() {
  input = 1;
}

void nextState() {
  state = FSM[state].next[input];
  // Intialize Button Pressed 
  input = 0;
}

void stateOutput() {
  pwmOut = FSM[state].out[PWM];
  ledOut = FSM[state].out[LED];
}

FSM Example 3

INPUT:

  • X: Button Pressed {0, 1}

  • Y: Object Detected {0, 1}

OUTPUT:

  • VEL {0%, 50% 100%}

  • LED {ON, OFF}

STATE:

  • S0: FAN OFF State

  • S1: FAN MID State

  • S2: FAN HIGH State

  • P_50: FAN 50% PAUSE State

  • P_100: FAN 100% PAUSE State

Mealy FSM Table

EXERCISE

Moore FSM Table

Example Code

// State definition
#define S0  0
#define S1  1
#define S2  2

const int ledPin = 13;
const int pwmPin = 11;
const int btnPin = 3;

int state = S0;
int bPressed = 0;
int ledOn = LOW;

void setup() {
  // [TO-DO] YOUR CODE GOES HERE
}

void loop() {
  // [TO-DO] YOUR CODE GOES HERE
    
  // Output State
  stateOutput();
  
  // [TO-DO] YOUR CODE GOES HERE
    
  // Calculate next state, then update State
  nextState();
  
  // [TO-DO] YOUR CODE GOES HERE
    
}

void pressed(){
  bPressed = 1;
}

void nextState(){
  // [TO-DO] YOUR CODE GOES HERE
  
  // Output
  analogWrite(pwmPin, pwm);
  digitalWrite(ledPin, ledState);
}

void stateOutput(){
  // [TO-DO] YOUR CODE GOES HERE
}
// State definition
#define S0    0   // Fan OFF
#define S1    1   // Fan vel = 50%
#define S2    2   // Fan vel = 100%
#define P50   3   // Pause (vel = 50%)
#define P100  4   // Pause (vel = 100%)

// Address number of output in array
#define PWM 0
#define LED 1

// State table definition
typedef struct {
  uint32_t out[2];      // output = FSM[state].out[PWM or LED]
  uint32_t next[2][2];  // nextstate = FSM[state].next[input X][input Y]
} State_t;

State_t FSM[5] = {
  { {0   , LOW }, {{S0  , S0}, {P50 , S1}} },
  { {80  , HIGH}, {{P50 , S1}, {P100, S2}} },
  { {160 , HIGH}, {{P100, S2}, {S0  , S0}} },
  { {0   , HIGH}, {{P50 , S1}, {P100, S2}} },
  { {0   , HIGH}, {{P100, S2}, {S0  , S0}} },
};

// Pin setting
const int ledPin = 13;
const int pwmPin = 11;
const int btnPin = 3;
const int trigPin = 10;
const int echoPin = 7;

unsigned char state = S0;
unsigned char input[2] = {0, 0};
unsigned char pwmOut = 0;
unsigned char ledOut = LOW;

unsigned long duration;
float distance;
int thresh = 5;

void setup() {  
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);

  // Initialize pwm pin as an output:
  pinMode(pwmPin, OUTPUT);
  
  // initialize the pushbutton pin as an interrupt input:
  pinMode(btnPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(btnPin), pressed, FALLING);

  // Initialize the trigger pin as an output
  pinMode(trigPin, OUTPUT);

  // Initialize the echo pin as an input
  pinMode(echoPin, INPUT);
  
  Serial.begin(9600);
}

void loop() {
  // Generate pwm singal on the trigger pin.
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  delayMicroseconds(10);

  // Distance is calculated using how much time it takes.
  duration = pulseIn(echoPin, HIGH);
  distance = (float)duration / 58.0;

  // Calculate next state. then update State
  nextState();

  // Output of states
  stateOutput();

  analogWrite(pwmPin, pwmOut);
  digitalWrite(ledPin, ledOut);

  Serial.print("distance = ");
  Serial.print(distance);
  Serial.println(" [cm]");
  
  delay(1000);
}

void pressed(){
  input[0] = 1;
  nextState();
  input[0] = 0;
}

void nextState(){
  if (distance < thresh)
    input[1] = 1;
  else
    input[1] = 0;
    
  // get nextState
  state = FSM[state].next[input[0]][input[1]];
}

void stateOutput(){
  pwmOut = FSM[state].out[PWM];
  ledOut = FSM[state].out[LED];  
}
PreviousLAB Report TemplateNextLAB: Portable Fan with mbed

Last updated 1 year ago

Was this helpful?

image
image
image
image
image