Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Lab2 Sei

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 11

MINISTERUL EDUCAȚIEI ȘI CERCETĂRII

AL REPUBLICII MOLDOVA
Universitatea Tehnică a Moldovei
Facultatea Calculatoare, Informatică şi Microelectronică
Departamentul Microelectronică și Inginerie Biomedicală

Raport
pentru lucrarea de laborator Nr.2

la cursul de “ Sisteme electronice incorporate”

A efectuat st. gr.:

A verificat:

Chișinău – 2024

Tema: Sisteme de Operare


Definire problemă:
Realizarea unei aplicații pentru MCU care va rula minim 3 task-uri in doua versiuni - Secvential si cu FreeRTOS
Aplicația va rula minim 3 task-uri printre care
1. Button Led - Schimbare stare LED la detecția unei apăsări pe buton.
2. un al doilea Led Intermitent în faza în care LED-ul de la primul Task e stins
3. Incrementare/decrementare valoare a unei variabile la apăsarea a doua butoane care va reprezenta numărul de
recurențe/timp în care ledul de la al doilea task se va afla într-o stare
4. Task-ul de Idle se va utiliza pentru afișarea stărilor din program, cum ar fi, afișare stare LED, și afișare mesaj la
detecția apăsării butoanelor, o implementare fiind ca la apăsarea butonului sa se seteze o variabila, iar la afișare mesaj
- resetare, implementând mecanismul provider/consumer.
1. Schema electrica in Wokwi:

2. Librarile necesare:
 Button.h si Button.cpp
Button.h:

// Button.h
#ifndef BUTTON_H
#define BUTTON_H

#include <Arduino.h>

class Button {
private:
int pin;
unsigned long lastPressTime;
unsigned long debounceDelay;
bool pressed;

public:
Button(int pin, unsigned long debounceDelay = 50);
void begin();
bool isPressed();
};

#endif

Button.cpp:
// Button.cpp

#include "Button.h"

Button::Button(int pin, unsigned long debounceDelay) {


this->pin = pin;
this->debounceDelay = debounceDelay;
this->lastPressTime = 0;
this->pressed = false;
}

void Button::begin() {
pinMode(pin, INPUT_PULLUP); // Assuming the button is connected between the pin and
ground
}

bool Button::isPressed() {
unsigned long currentTime = millis();
bool currentState = digitalRead(pin) == LOW; // LOW when button is pressed due to
INPUT_PULLUP

if (currentState && (currentTime - lastPressTime >= debounceDelay)) {


// Button is pressed and debounce delay has passed since last press
lastPressTime = currentTime;
return true;
}

return false;
}

 RGB_LED.h

#ifndef RGB_LED_H_
#define RGB_LED_H_

#include "Arduino.h"

// Abstract interface for controlling pins


class PinController {
public:
virtual void setPin(int pin, bool state) = 0;
};

// Implementation for Arduino


class ArduinoPinController : public PinController {
public:
void setPin(int pin, bool state) override {
digitalWrite(pin, state ? HIGH : LOW);
}
};

class RGB_LED {
public:
RGB_LED(int redPin, int greenPin, int bluePin, PinController* pinController) :
_redPin(redPin), _greenPin(greenPin), _bluePin(bluePin),
_pinController(pinController) {
_pinController->setPin(_redPin, LOW);
_pinController->setPin(_greenPin, LOW);
_pinController->setPin(_bluePin, LOW);
}

void setColor(bool red, bool green, bool blue) {


_pinController->setPin(_redPin, red);
_pinController->setPin(_greenPin, green);
_pinController->setPin(_bluePin, blue);
}

private:
int _redPin;
int _greenPin;
int _bluePin;
PinController* _pinController;
};

#endif /* RGB_LED_H_ */

 Comunication.h si Comunication.cpp
Comunication.h

#ifndef COMUNICATION_H
#define COMUNICATION_H

#include <Arduino.h>
#include <stdio.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h> // Change to LiquidCrystal_I2C.h for I2C display support
#include <Keypad.h>
#include "config.h"

void stdio_serial_setup(void);
void stdio_lcd_and_keypad(void);
void stdio_lcd_and_serial(void);

#endif

Comunication.cpp

#include "Comunication.h"
#include <config.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>

static FILE stream = {0};

// Define your LCD I2C address and dimensions


#define LCD_ADDRESS 0x27
#define LCD_COLUMNS 16
#define LCD_ROWS 2

// Replace LiquidCrystal lcd(LCD_RS, LCD_ENABLE, LCD_D4, LCD_D5, LCD_D6, LCD_D7);


// with LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);
LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);

// Define your keypad pins and keys


static char keys[KEYPAD_ROWS][KEYPAD_COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};

byte rowPins[KEYPAD_ROWS] = {KEYPAD_R1, KEYPAD_R2, KEYPAD_R3, KEYPAD_R4};


byte colPins[KEYPAD_COLS] = {KEYPAD_C1, KEYPAD_C2, KEYPAD_C3, KEYPAD_C4};

Keypad kpd = Keypad(makeKeymap(keys), rowPins, colPins, KEYPAD_ROWS, KEYPAD_COLS);

int stdio_lcd_putchar(char ch, FILE *stream) {


if (ch != '\f') {
if (ch != '\n') {
lcd.write(ch);
}
} else {
lcd.clear();
}
return 0;
}

int stdio_keypad_getchar(FILE *stream) {


while (1) {
char key = kpd.getKey();
if (key) {
return key;
}
}
return 0;
}

int stdio_serial_putchar(char ch, FILE *stream) {


Serial.write(ch);
return 0;
}

int stdio_serial_getchar(FILE *stream) {


while (!Serial.available());
return Serial.read();
}

int stdio_lcd_and_serial_putchar(char ch, FILE *stream) {


stdio_lcd_putchar(ch, stream);
stdio_serial_putchar(ch, stream);
return 0;
}

void stdio_serial_setup(void) {
Serial.begin(BAUDRATE);
fdev_setup_stream(
&stream,
stdio_serial_putchar,
stdio_serial_getchar,
_FDEV_SETUP_RW
);
stdin = &stream;
stdout = &stream;
}

void stdio_lcd_and_keypad(void) {

// Initialize the LCD


lcd.init();
lcd.backlight();
lcd.clear();
fdev_setup_stream(
&stream,
stdio_lcd_putchar,
stdio_keypad_getchar,
_FDEV_SETUP_RW
);
stdin = &stream;
stdout = &stream;
}

void stdio_lcd_and_serial(void) {
// Initialize the LCD
lcd.init();
lcd.backlight();
Serial.begin(BAUDRATE);
fdev_setup_stream(
&stream,
stdio_lcd_and_serial_putchar,
stdio_keypad_getchar,
_FDEV_SETUP_RW
);
stdin = &stream;
stdout = &stream;
}

 config.h
#ifndef CONFIG_H
#define CONFIG_H
#define BAUDRATE 9600
// Define pin mappings
#define LCD_VCC 26
#define LCD_GND 2
#define LCD_SDA 20
#define LCD_SCL 21

#define RGB_COM 53
#define RGB_R 13
#define RGB_G 12
#define RGB_B 11

#define BTN1_PIN 22
#define BTN2_PIN 23
#define BTN3_PIN 24

#define KEYPAD_R1 27
#define KEYPAD_R2 26
#define KEYPAD_R3 29
#define KEYPAD_R4 28

#define KEYPAD_C1 31
#define KEYPAD_C2 30
#define KEYPAD_C3 33
#define KEYPAD_C4 32

// Define keypad size


#define KEYPAD_ROWS 4
#define KEYPAD_COLS 4
// Define pin mappings for keypad
#define ROWS 4
#define COLS 4
//byte ROW_PINS[ROWS] = {KEYPAD_R1, KEYPAD_R2, KEYPAD_R3, KEYPAD_R4};
//byte COL_PINS[COLS] = {KEYPAD_C1, KEYPAD_C2, KEYPAD_C3, KEYPAD_C4};

// Define LCD size


#define LCD_ADDRESS 0x27
#define LCD_COLUMNS 16
#define LCD_ROWS 2

#endif

 main.cpp SO Secvential
#include <Arduino.h>
#include "Button.h"
#include "config.h"
#include "RGB_LED.h"
#include "Comunication.h"
#include <TaskScheduler.h>
Button button_r (BTN1_PIN,150);
Button button_g (BTN2_PIN,150);
Button button_b (BTN3_PIN,150);

bool redLedState = false;


bool greenLedState = false;
bool blueLedState = false;
ArduinoPinController arduinoPinController;
RGB_LED rgbLed(RGB_R, RGB_G, RGB_B, &arduinoPinController);

Scheduler scheduler;
Task t1(300, TASK_FOREVER, [](){
if (button_r.isPressed()) {
redLedState=!redLedState;}
if (redLedState==true) {
rgbLed.setColor(1, 0, 0);
}});

int freq = 1;

Task t2(250, TASK_FOREVER, [](){


if (!button_r.isPressed() && !redLedState) {
static bool ledState = false;
ledState = !ledState;
if (ledState) {
rgbLed.setColor(0, 1, 0); // Turn on green LED
} else {
rgbLed.setColor(0, 0, 0); // Turn off green LED
}
delay(1000 / freq); // Adjust blinking frequency
} else {
rgbLed.setColor(0, 0, 0); // Turn off green LED if red LED is on
}
});

Task t3(150, TASK_FOREVER, [](){


if (button_g.isPressed()) {
freq++; // Increment frequency
}
if (button_b.isPressed()) {
freq = max(1, freq - 1); // Decrement frequency, ensuring it's not less than 1
}
});

Task tIdle(800, TASK_FOREVER, [](){


printf("\f");
if (redLedState==true) {
printf("Task1\n\r");
printf("Led On (RED)\n\r");
delay(100);
} else {
printf("Task2 \n\r");
printf("Blink \n\r");
printf("freq: %d", freq);
}
});

void setup() {
button_b.begin();
button_g.begin();
button_r.begin();
//stdio_serial_setup(); // Initialize Serial setup
stdio_lcd_and_keypad();

scheduler.addTask(t1);
scheduler.addTask(t2);
scheduler.addTask(t3);
scheduler.addTask(tIdle);
t1.enable();
t2.enable();
t3.enable();
tIdle.enable();
scheduler.startNow(); // Start the scheduler
}
void loop() {

scheduler.execute();
}

Main.cpp FreeRTOS

#include <Arduino_FreeRTOS.h>
#include <Arduino.h>
#include "Button.h"
#include "config.h"
#include "RGB_LED.h"
#include "Comunication.h"

// Task function prototypes


void task1(void *pvParameters);
void task2(void *pvParameters);
void task3(void *pvParameters);
void idle_task(void *pvParameters);
Button button_r (BTN1_PIN,150);
Button button_g (BTN2_PIN,150);
Button button_b (BTN3_PIN,150);

bool redLedState = false;


bool greenLedState = false;
bool blueLedState = false;
ArduinoPinController arduinoPinController;
RGB_LED rgbLed(RGB_R, RGB_G, RGB_B, &arduinoPinController);
// Task handles
TaskHandle_t Task1_Handle;
TaskHandle_t Task2_Handle;
TaskHandle_t Task3_Handle;
TaskHandle_t IDLE_Handle;
void setup() {
button_b.begin();
button_g.begin();
button_r.begin();
stdio_serial_setup(); // Initialize Serial setup
//stdio_lcd_and_keypad();
xTaskCreate(task1, "Task1", 1000, NULL, 1, &Task1_Handle);
xTaskCreate(task2, "Task2", 1000, NULL, 1, &Task2_Handle);
xTaskCreate(task3, "Task3", 1000, NULL, 1, &Task3_Handle);
xTaskCreate(idle_task, "IDLE", 1000, NULL, 1, &IDLE_Handle);
}

void loop() {
// This function should remain empty when using FreeRTOS tasks
}

void task1(void *pvParameters) {


(void)pvParameters; // Unused parameter
for (;;) {
// Task 1 code here
//printf("Task 1 running...");
if (button_r.isPressed()) {
redLedState=!redLedState;}
if (redLedState==true) {
rgbLed.setColor(1, 0, 0);
};
// Delay to simulate task execution time
// vTaskDelay(pdMS_TO_TICKS(1000)); // Delay for 1000 milliseconds
}
}
int freq = 1;
void task2(void *pvParameters) {
(void)pvParameters; // Unused parameter
const TickType_t ticks = pdMS_TO_TICKS(1000 / freq);
for (;;) {
if (!button_r.isPressed() && !redLedState) {
static bool ledState = false;
ledState = !ledState;
if (ledState) {
rgbLed.setColor(0, 1, 0); // Turn on green LED
} else {
rgbLed.setColor(0, 0, 0); // Turn off green LED
}
vTaskDelay(ticks);
} else {
rgbLed.setColor(0, 0, 0); // Turn off green LED if red LED is on
}
}
}
void task3(void *pvParameters) {
(void)pvParameters; // Unused parameter

for (;;) {
if (button_g.isPressed()) {
freq++; // Increment frequency
}
if (button_b.isPressed()) {
freq = max(1, freq - 1); // Decrement frequency, ensuring it's not less than 1
}
}
}
void idle_task (void *pvParameters){
(void)pvParameters;
for(;;){
printf("\f");
if (redLedState==true) {
printf("Task1\n\r");
printf("Led On (RED)\n\r");
//delay(100);
} else {
printf("Task2 \n\r");
printf("Blink \n\r");
printf("freq: %d", freq);
}
}
}

You might also like