Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .mbed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ROOT=.
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
# ArmBookCurso2024

Primer ejemplo básico para aprender a usar las herramientas

**Título:** Control de Sistema de Tratamiento de Agua

**Alumno:** Jesús García

**Objetivo:** Desarrollar un sistema que monitorice y controle un proceso de tratamiento de agua.

**Descripción:**

El sistema controlará el suministro y la producción de agua ultrapura a través de un sistema de tratamiento mediante ósmosis inversa.

Entrega TP1
- Encender y apagar el sistema, en este caso ya se habia implementado maquina de estado para ese control por que se evidenció problema de rebote y era muy dificil poder prender o apagar el sistema. el Led1 es el indicador de este servicio.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Encender y apagar el sistema: en este caso ya se habia implementado
    Van dos puntos luego de sistema.

- Controlar las presiones de corte mínimas y máximas para el encendido de las bombas de abastecimiento principal, este item se esta emulando con un potenciometro y se realiza una conversión sencilla que me permite obtener la presión de entrada en PSI y prender o apagar la bomba P1 según la presiones altas y bajas configuradas para apagar el sistema, el monitoreo se realiza cada 1.5 segundos, evitando ser bloqueante.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"bombas de abastecimiento principal: este..."

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No me queda claro por qué al monitorear cada 1.5 se evita que sea bloqueante. Digo, lo que importa no es cada cuánto tiempo se puede bloquear, sino una vez que llega a la situación bloqueante, cuánto tiempo se queda sin salir de la situación bloqueante. Todo esto siempre en relación con la dinámica del sistema: si el sistema requiere demorar de décimas de milisegundos, entonces un bloquedo de cientos de milisegundos, por ejemplo, es una barbaridad.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, más abajo encontré la parte del código en la que haces que no sea tan molesto ni tan bloqueante el delay de 1,5 segundos, al separarlo en delays más pequeños.

- Ajustar la frecuencia de funcionamiento de la bomba que proporciona presión a las membranas de filtración. Se ha implementado una maquina de estado para el manejo de un teclado 4x3, todavia no se ha implementado.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

las membranas de filtración: Se ha

- Envio por UART, de momento se esta enviando cada 3 segundos el estado del sistema y la presión actual del sistema.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

envio por UART: de momento se e

Y además, ojo que "envio" debe llevar tilde en la "i", o sea, Envío.



**Plataforma de desarrollo:** NUCLEO-144

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

¿A qué plataforma te referís? No me doy cuenta:


**Periféricos a utilizar:**
- **USER BUTTON:** Para iniciar o apagar el sistema.
- **LED 1:** Indica el estado de funcionamiento del sistema.
- **ANALOG IN 1:** Emula un sensor de presión.
- **UART:** Se utiliza para enviar información sobre el estado del sistema a una PC.


3 changes: 3 additions & 0 deletions README.md.bak
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# ArmBookCurso2024

Primer ejemplo básico para aprender a usar las herramientas
340 changes: 336 additions & 4 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,344 @@
//=====[Libraries]=============================================================
#include "mbed.h"

//=====[Defines]===============================================================
#define TIME_INCREMENT_MS 10

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

En cada una de las definiciones de tiempos debería quedar claras las unidades en las que están expresadas las cifras.
En el caso de TIME_INCREMENT dice "_MS", pero en los demas casos no se indica nada.

#define TIME_BLINK_LED_SISTEM 1000
#define TIME_CHECK_PRESSURE 1500
#define TIME_SEND_DATA 3000
#define DEBOUNCE_BUTTON_TIME_MS 40
#define KEYPAD_NUMBER_OF_ROWS 4
#define KEYPAD_NUMBER_OF_COLS 3

//=====[Declaration and initialization of public global objects]===============
DigitalIn onOffButton(BUTTON1);
DigitalIn upButton(D0);
DigitalIn downButton(D1);
DigitalIn levelHighSensor(D2);
DigitalIn levelMediumSensor(D3);
DigitalIn levelLowSensor(D4);

DigitalOut ledSistem(LED1);
DigitalOut pumpP1(LED2);
DigitalOut pumpP2(LED3);
DigitalOut buzzer(D7);

UnbufferedSerial uartUsb(USBTX, USBRX, 115200);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considero que sería bueno que oportunamente uses format() para explicitar la configuración de la comunicación:

https://os.mbed.com/docs/mbed-os/v6.16/mbed-os-api-doxy/classmbed_1_1_serial_base.html#a8274461aa9a0611c28c4c6aeae665277


AnalogIn potentiometer(A0);


//=====[Declaration of public data types]======================================

typedef enum {
BUTTON_UP,
BUTTON_DOWN,
BUTTON_FALLING,
BUTTON_RISING
} onOffButtonState_t;

typedef enum {
MATRIX_KEYPAD_SCANNING,
MATRIX_KEYPAD_DEBOUNCE,
MATRIX_KEYPAD_KEY_HOLD_PRESSED
} matrixKeypadState_t;

//=====[Declaration and initialization of public global variables]=============
bool onOffStatus = false;
bool onOffStatusLed = false;
bool evento_boton = false;
int blinkLedSistem = 0;

int timeCheckPressure=0;
int counterEventsBtnOff = 0;
int accumulatedDebounceButtonTime = 0;
int numberOfEnterButtonReleasedEvents = 0;
int timeAccumulatedSendData=0;
int timeAccumulatedCheckPressure=0;


onOffButtonState_t enterButtonState;


char buffer[50];

DigitalOut keypadRowPins[KEYPAD_NUMBER_OF_ROWS] = {PE_5, PE_6, PE_3, PF_8};
DigitalIn keypadColPins[KEYPAD_NUMBER_OF_COLS] = {PF_7, PF_9, PG_1};

int accumulatedDebounceMatrixKeypadTime = 0;
char matrixKeypadLastKeyPressed = '\0';
char matrixKeypadIndexToCharArray[] = {
'1', '2', '3',
'4', '5', '6',
'7', '8', '9',
'*', '0', '#',
};
matrixKeypadState_t matrixKeypadState;


//=====[Declarations (prototypes) of public functions]=========================

void inputsInit();
void outputsInit();

void statusSistem();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

System

void statusLed();
void debounceButtonInit();
bool debounceButtonUpdate();
float readPressureM1();
void checkpressure();
void statePump1();

void sendData();
void availableCommands();

void matrixKeypadInit();
char matrixKeypadScan();
char matrixKeypadUpdate();

//=====[Main function, the program entry point after power on or reset]========

int main()
{
DigitalIn B1_USER(BUTTON1);
inputsInit();
outputsInit();
while (true) {
statusSistem();
statusLed();
checkpressure();
sendData();
HAL_Delay(TIME_INCREMENT_MS);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dónde está definida esta función "HAL_Delay".

}
}

DigitalOut LD1(LED1);
//=====[Implementations of public functions]===================================

while (true) {
LD1 = B1_USER;
void inputsInit()
{
onOffButton.mode(PullDown);
upButton.mode(PullDown);
downButton.mode(PullDown);
levelHighSensor.mode(PullDown);
levelMediumSensor.mode(PullDown);
levelLowSensor.mode(PullDown);
debounceButtonInit();
matrixKeypadInit();
}

void outputsInit()
{
ledSistem = 0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Buscar todas las instancias de "Sistem" y cambiarlas por "System", o bien por "Sistema"

pumpP1 = false;
pumpP2 = 0;
buzzer =0;
}

void statusSistem()
{
evento_boton=debounceButtonUpdate();
if (evento_boton){
onOffStatus=!onOffStatus;
}

}

void statusLed()
{
if (onOffStatus)
{
if(blinkLedSistem <= TIME_BLINK_LED_SISTEM){
blinkLedSistem = blinkLedSistem+TIME_INCREMENT_MS;
}
else{
blinkLedSistem=0;
ledSistem=!ledSistem;
}
}
else{
ledSistem=0;
}
}


void sendData()
{
if (timeAccumulatedSendData <= TIME_SEND_DATA){
timeAccumulatedSendData=timeAccumulatedSendData+TIME_INCREMENT_MS;
}
else{
int length = snprintf(buffer, sizeof(buffer), "La presión de entrada es: %.2f psi, ", readPressureM1());
uartUsb.write(buffer, length);
int length1 = snprintf(buffer, sizeof(buffer), "el sistema esta: %s, \n\r", pumpP1 ? "encendido" : "apagado");
uartUsb.write(buffer, length1);
timeAccumulatedSendData=0;
}
}

void debounceButtonInit()
{
if( onOffButton == 1) {
enterButtonState = BUTTON_DOWN;
} else {
enterButtonState = BUTTON_UP;
}
}

bool debounceButtonUpdate()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fijate que acá estás usando una Máquina de Estado, y se supone que en el TP2 recién se incorpora el tema de FSM, pero sin embargo si lo sabes usar lo podes usar.

{
bool enterButtonReleasedEvent = false;
switch( enterButtonState ) {

case BUTTON_UP:
if( onOffButton ) {
enterButtonState = BUTTON_FALLING;
accumulatedDebounceButtonTime = 0;
}
break;

case BUTTON_FALLING:
if( accumulatedDebounceButtonTime >= DEBOUNCE_BUTTON_TIME_MS ) {
if( onOffButton ) {
enterButtonState = BUTTON_DOWN;
} else {
enterButtonState = BUTTON_UP;
}
}
accumulatedDebounceButtonTime = accumulatedDebounceButtonTime +
TIME_INCREMENT_MS;
break;

case BUTTON_DOWN:
if( !onOffButton ) {
enterButtonState = BUTTON_RISING;
accumulatedDebounceButtonTime = 0;
}
break;

case BUTTON_RISING:
if( accumulatedDebounceButtonTime >= DEBOUNCE_BUTTON_TIME_MS ) {
if( !onOffButton ) {
enterButtonState = BUTTON_UP;
enterButtonReleasedEvent = true;
} else {
enterButtonState = BUTTON_DOWN;
}
}
accumulatedDebounceButtonTime = accumulatedDebounceButtonTime +
TIME_INCREMENT_MS;
break;

default:
debounceButtonInit();
break;
}
return enterButtonReleasedEvent;

}


void matrixKeypadInit()
{
matrixKeypadState = MATRIX_KEYPAD_SCANNING;
int pinIndex = 0;
for (pinIndex = 0; pinIndex < KEYPAD_NUMBER_OF_COLS; pinIndex++) {
(keypadColPins[pinIndex]).mode(PullUp);
}
}

char matrixKeypadScan()
{
int row = 0;
int col = 0;
int i = 0;

for( row=0; row<KEYPAD_NUMBER_OF_ROWS; row++ ) {

for( i=0; i<KEYPAD_NUMBER_OF_ROWS; i++ ) {
keypadRowPins[i] = 1;
}

keypadRowPins[row] = 0;

for( col=0; col<KEYPAD_NUMBER_OF_COLS; col++ ) {
if( keypadColPins[col] == 1 ) {
return matrixKeypadIndexToCharArray[row*KEYPAD_NUMBER_OF_ROWS + col];
}
}
}
return '\0';
}

char matrixKeypadUpdate()
{
char keyDetected = '\0';
char keyReleased = '\0';

switch( matrixKeypadState ) {

case MATRIX_KEYPAD_SCANNING:
keyDetected = matrixKeypadScan();
if( keyDetected != '\0' ) {
matrixKeypadLastKeyPressed = keyDetected;
accumulatedDebounceMatrixKeypadTime = 0;
matrixKeypadState = MATRIX_KEYPAD_DEBOUNCE;
}
break;

case MATRIX_KEYPAD_DEBOUNCE:
if( accumulatedDebounceMatrixKeypadTime >=
DEBOUNCE_BUTTON_TIME_MS ) {
keyDetected = matrixKeypadScan();
if( keyDetected == matrixKeypadLastKeyPressed ) {
matrixKeypadState = MATRIX_KEYPAD_KEY_HOLD_PRESSED;
} else {
matrixKeypadState = MATRIX_KEYPAD_SCANNING;
}
}
accumulatedDebounceMatrixKeypadTime =
accumulatedDebounceMatrixKeypadTime + TIME_INCREMENT_MS;
break;

case MATRIX_KEYPAD_KEY_HOLD_PRESSED:
keyDetected = matrixKeypadScan();
if( keyDetected != matrixKeypadLastKeyPressed ) {
if( keyDetected == '\0' ) {
keyReleased = matrixKeypadLastKeyPressed;
}
matrixKeypadState = MATRIX_KEYPAD_SCANNING;
}
break;

default:
matrixKeypadInit();
break;
}
return keyReleased;
}


float readPressureM1() {
float analogValue = potentiometer.read();
float voltagePsi= (analogValue * 3.3)*30;
float pressureM1=voltagePsi;

return pressureM1;
}

void checkpressure() {
//verifica presion cada 1.5 seg
if (timeAccumulatedCheckPressure <= TIME_CHECK_PRESSURE){
timeAccumulatedCheckPressure=timeAccumulatedCheckPressure+TIME_INCREMENT_MS;
}
else{
int valuePressureM1 = readPressureM1();

if (valuePressureM1 <= 5) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No se entiende bien de dónde salen estos valores mágicos, como 5, 6 y 75. Deberían estar en la zona de definiciones.

pumpP1 = false;
} else if (valuePressureM1 >= 6 && valuePressureM1 <= 75) {
pumpP1 = true;
} else {
pumpP1 = false;
}
timeAccumulatedCheckPressure=0;
}
}
2 changes: 1 addition & 1 deletion mbed-os.lib
Original file line number Diff line number Diff line change
@@ -1 +1 @@
https://github.com/ARMmbed/mbed-os.git#26606218ad9d1ee1c8781aa73774fd7ea3a7658e
https://github.com/ARMmbed/mbed-os.git#17dc3dc2e6e2817a8bd3df62f38583319f0e4fed