|
1
|
Programación / .NET (C#, VB.NET, ASP) / Leer bien los datos recibidos.
|
en: 15 Marzo 2025, 20:37 pm
|
Buenas comper@s: Uso comunicación por el puerto serie /USB con Arduino y RealTerm para probar y funciona. Envío el comando tal cual, por ejemplo, B\r desde RealTerm o PuTTY, y recibe el comando exactamente tal cual quiero desde Arduino: #Comando B recibido\r Ver zoom. El problema de C# .net 8.0 usando Windows Form, no lee bien y llevo horas y horas. En mi caso, en vez de usar RealTerm, quiero usar el mio propio hecho con C#. Al enviar comandos como en este ejemplo, B\r a Arduino, lo lee bien, el problema es al devolver los datos que si lo devuelve y bien y C# no lo interpreta bien. O no recibe los datos, lo recibes a medias, o entre medios hace un salto de línea por la cara, hace cosas muy raras. Código Arduino:#include <LiquidCrystal.h> // Inicializa la librería con sus pines indicados LiquidCrystal lcd(8, NULL, 9, 4, 5, 6, 7); // Definir el pin para la luz de fondo y el LED const byte LuzFondo = 10; const byte Led = 13; // Variable para almacenar el comando recibido String comando = ""; // Asegúrate de declarar la variable de tipo String char caracter; void setup() { // Inicializa el LCD lcd.begin(16, 2); lcd.print("Esperando comando"); // Inicia la comunicación serial Serial.begin(2400); delay(1000); // Espera para asegurar que el LCD se inicialice } void loop() { // Mientras haya datos disponibles en el puerto serie, los leemos carácter a carácter while (Serial.available() > 0) { caracter = Serial.read(); // Leer un carácter del puerto serie comando.concat(caracter); // Concatenar el carácter al comando delay(10); // Pequeña espera para no saturar el canal serie } // Verificamos si el comando es "B\r" o "X72\r" y respondemos en consecuencia if (comando == "B\r") { digitalWrite(Led, HIGH); // Enciende el Led 13 Serial.write("#Comando B recibido\r"); // Envía el mensaje de vuelta a C# lcd.setCursor(0, 0); lcd.print("Comando B "); // Muestra en el LCD } else if (comando == "X72\r") { digitalWrite(Led, LOW); // Apaga el Led 13 Serial.write("#Comando X72 recibido\r"); // Envía el mensaje de vuelta a C# lcd.setCursor(0, 0); lcd.print("Comando X72 "); // Muestra en el LCD } else if (comando == "X5\r") { digitalWrite(Led, LOW); // Apaga el Led 13 Serial.write("#Comando X5 recibido\r"); // Envía el mensaje de vuelta a C# lcd.setCursor(0, 0); lcd.print("Comando X5 "); // Muestra en el LCD } // Limpiamos la cadena de comando para volver a recibir el siguiente comando comando = ""; }
Código C#: using System.Text; using System.IO.Ports; namespace SAI_Arduino_LCD_01 { public partial class Form1 : Form { private SerialPort puertoSerie; private string lastReceivedData = ""; // Variable para guardar el último dato recibido public Form1() { InitializeComponent(); InicializarPuertoSerie(); } // Método para inicializar la configuración del puerto serie private void InicializarPuertoSerie() { puertoSerie = new SerialPort () { BaudRate = 2400, Parity = Parity.None, // Esquema para comprobar la paridad de cada byte recibido. StopBits = StopBits.One, // Número de bits de parada por byte. DataBits = 8, // Número de bits de datos por byte. Handshake = Handshake.None, // Protocolo de establecimiento. Encoding = Encoding.GetEncoding(28591), // Codificación. DtrEnable = true, // Línea de terminal de datos. RtsEnable = true, // Línea de solicitud. ReadTimeout = 500, // Tiempo de espera de lectura en ms. WriteTimeout = 500, // Tiempo de espera de escritura en ms. DiscardNull = false, // Descartar bytes nulos recibidos. ParityReplace = 63, // Reemplaza los bytes recibidos con errores de paridad. ReadBufferSize = 4096, // Tamaño del búfer de lectura en bytes. WriteBufferSize = 2018, // Tamaño del búfer de escritura en bytes. ReceivedBytesThreshold = 1 // Número de bytes que se necesitan. }; puertoSerie.DataReceived += PuertoSerie_DataReceived; // Suscribimos al evento } // Evento que se activa cuando se reciben datos del puerto serie private void PuertoSerie_DataReceived(object sender, SerialDataReceivedEventArgs e) { try { // Verificamos si el puerto está abierto if (!puertoSerie.IsOpen) { ActualizarRichTextBox("Puerto no abierto."); return; } // Leer todos los datos disponibles hasta que no haya más string data = puertoSerie.ReadExisting(); // Usamos ReadExisting para leer todo // Solo actualizar si los datos recibidos son diferentes de los anteriores if (!string.IsNullOrEmpty(data) && data != lastReceivedData) { lastReceivedData = data; // Actualizar el último dato recibido ActualizarRichTextBox(data); // Mostrar los datos recibidos } } catch (TimeoutException) { // Si hay un Timeout, podemos ignorar y no mostrar nada } catch (Exception ex) { ActualizarRichTextBox("Error: " + ex.Message + "\r\n"); } } // Método para actualizar el RichTextBox de manera segura desde cualquier hilo private void ActualizarRichTextBox(string mensaje) { if (InvokeRequired) { Invoke (new Action <string>(ActualizarRichTextBox ), mensaje ); } else { richTextBox1.AppendText(mensaje + "\r\n"); } } // Método para enviar un comando por el puerto serie private void EnviarComando(string comando) { try { // Verificar si el puerto está abierto if (!puertoSerie.IsOpen) { puertoSerie.Open(); } // Enviar cada carácter del comando como valor ASCII foreach (char c in comando) { puertoSerie .Write(new byte[] { (byte)c }, 0, 1); // Escribir un byte correspondiente al carácter ASCII } // Enviar el retorno de carro \r como un byte puertoSerie .Write(new byte[] { 13 }, 0, 1); // ASCII de '\r' es 13 // Esperar un breve tiempo para asegurar que Arduino procese el comando antes de continuar Thread.Sleep(200); // Ajusta el tiempo según sea necesario ActualizarRichTextBox("Enviado: " + comando + "\r\n"); } catch (UnauthorizedAccessException ex) { MessageBox.Show("El puerto COM está en uso por otro proceso. Error: " + ex.Message); } catch (Exception ex) { MessageBox.Show("Error al intentar enviar el comando: " + ex.Message); } } // Cerrar el puerto de manera segura cuando se cierre el formulario private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (puertoSerie.IsOpen) { try { puertoSerie.Close(); } catch (Exception ex) { MessageBox.Show("Error al cerrar el puerto: " + ex.Message); } } } private void Form1_Load(object sender, EventArgs e) { try { string[] puertos = SerialPort.GetPortNames(); comboBox_Puertos.Items.AddRange(puertos); // Llenar el ComboBox con los puertos disponibles if (comboBox_Puertos.Items.Count > 0) { comboBox_Puertos.SelectedIndex = 0; // Seleccionar el primer puerto automáticamente } } catch (Exception ex) { MessageBox.Show("Error al cargar los puertos: " + ex.Message); } } // Método para conectar con el puerto seleccionado private void btnConectar_Click(object sender, EventArgs e) { if (comboBox_Puertos.SelectedItem == null) { MessageBox.Show("Por favor, selecciona un puerto COM antes de intentar conectar."); return; } string puertoSeleccionado = comboBox_Puertos.SelectedItem.ToString(); puertoSerie.PortName = puertoSeleccionado; // Configurar el puerto try { // Verificar si el puerto ya está abierto y cerrarlo si es necesario if (puertoSerie.IsOpen) { puertoSerie.Close(); ActualizarRichTextBox("Puerto cerrado previamente.\r\n"); } // Abrir el puerto puertoSerie.Open(); ActualizarRichTextBox("Conexión exitosa con " + puertoSeleccionado + "\r\n"); } catch (Exception ex) { MessageBox.Show("Error al abrir el puerto: " + ex.Message); } } // Métodos de comando private void button_Comando_B_Click(object sender, EventArgs e) => EnviarComando("B"); private void button_Comando_X72_Click(object sender, EventArgs e) => EnviarComando("X72"); private void button_Comando_X5_Click(object sender, EventArgs e) => EnviarComando("X5"); } }
Con RealTerm, Putty y otros, funciona bien. ¿En qué estoy fallando? Un cordial saludo y muchas gracias por su tiempo.
|
|
|
2
|
Programación / .NET (C#, VB.NET, ASP) / El depurador ahora muestra valores devueltos insertados con ayuda de IA para mejorar la eficacia.
|
en: 14 Noviembre 2024, 10:50 am
|
Hola gente: ¿Cómo están todos?  Actualizado el Visual Studio Community 2022 (Gratuito), por ahora no se ha nombrado uno nuevo completo. Una de las novedades de ahora es esto indicado abajo. El depurador de Visual Studio muestra ahora valores insertados para las instrucciones de devolución, respondiendo así a una de las características más solicitadas por la comunidad de desarrolladores.
Esta mejora le permite ver los valores exactos que devuelven las funciones directamente en el código, eliminando la necesidad de código adicional o variables temporales para inspeccionar los valores de devolución.
 Valores devueltos insertados
Con GitHub Copilot, puede ir más allá utilizando la opción Preguntar a Copilot al mantener el mouse para analizar los valores devueltos directamente en Visual Studio, lo que le permite abordar los problemas de inmediato.
Se admite tanto en código nativo como administrado.Por curiosidad hice este ejemplo en C# y no me funciona. using System; namespace Metodo_Consola_01 { internal class Program { static void Main(string[] args) { int resultado = Sumar(5, 10); Console.WriteLine($"El resultado de la suma es: {resultado}."); // Pulse cualquier tecla para salir. Console.ReadKey(); } static int Sumar(int a, int b) { return a + b; } } }
Al compilar funciona y el resultado da 15. Se trata de pasar el ratón por encima del IDE sin compilar nada y muestra los resultados. A mi no me funciona ni a la de tres. ¿A alguien le ha funcionado? Gracias.
|
|
|
3
|
Programación / Programación C/C++ / Controlar variable
|
en: 31 Octubre 2024, 18:15 pm
|
Tengo esta variable declarada en C++ nativo con Visual Community 2022. char lectura[50] = { 0 };
Al recibir datos, parece que como máximo recibo 50 caracteres o bytes. if (n > 0) { lectura[n] = '\0'; // Finaliza la cadena. cout << "Recibido: " << lectura << endl; cout << "-------------------" << endl; }
El dato que recibo por ejemplo debe ser exactamente esto: ON - Led encendido.Si miro la variable en el IDE, me muestra esto: Ver zoom. Al recibir esos datos quiero hacer algo como esto: if (lectura == "ON - Led encendido.") { cout << "Recibido: " << lectura << endl; }
¿Hay alguna manera de quitar los 0'\0' datos restantes que molestan? Saludos.
|
|
|
4
|
Programación / Programación C/C++ / Usar switch o otra manera para poner en gotoXY textos
|
en: 29 Octubre 2024, 07:01 am
|
Buenas camaradas: Usando este código. Recibo datos por el puerto serie. // Lee datos del puerto serie. int n = Puerto->ReadData(lectura, sizeof(lectura) - 1); // Recibe datos del puerto serie. if (n > 0) { lectura[n] = '\0'; // Finaliza la cadena. switch (lectura) { default: break; } cout << "Recibido: " << lectura << endl; cout << "-------------------" << endl; }
Justo en switch (lectura) me da error de este tipo. Gravedad Código Descripción Proyecto Archivo Línea Estado suprimido Detalles Error C2450 una expresión switch de tipo "char [50]" no es válida Arduino y puerto serie CPP Consola 01 D:\Visual Studio 2022\Arduino y puerto serie CPP Consola 01\Arduino y puerto serie CPP Consola 01\Arduino y puerto serie CPP Consola 01.cpp 114 Dentro de los case quiero poner sus coordenadas para poner los textos en cualquier zona de la pantalla con gotoXY que es este. // Función posición del cursor. void gotoxy(int ancho_x, int alto_y) { HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE); COORD dwPos{}; dwPos.X = ancho_x; dwPos.Y = alto_y; SetConsoleCursorPosition(hcon, dwPos); }
¿Alguna solución? Código C++ nativo completo hecho con Visual Studio 2022. #include <iostream> #include <windows.h> // Para mostrar texto en el título de la ventana. #include "SerialClass.h" using namespace std; //using std::cout; //using std::cin; void ConfigurarConsola() { #pragma region "Configuración ventana." // Mostrar caracteres correctamente en pantalla y título de la ventana. SetConsoleOutputCP(CP_UTF8); wchar_t titulo[128]; MultiByteToWideChar(CP_UTF8, 0, "Título: Arduino puerto serie - C++ nativo", -1, titulo, 128); SetConsoleTitleW(titulo); // Tamaño de la pantalla. Se cambia en los dos últimos dígitos. SMALL_RECT r = { 0, 0, 120, 40 }; // X = 80, Y = 20. SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &r); // Cambio color de fondo 6 (amarillo / naranja), color letras 0 (negro). system("color 60"); // Color de fonde y texto. // Ocultar cursor. CONSOLE_CURSOR_INFO cci; GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci); cci.bVisible = FALSE; // FALSE oculta. TRUE muestra cursor. SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci); #pragma endregion } // Función posición del cursor. void gotoxy(int ancho_x, int alto_y) { HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE); COORD dwPos{}; dwPos.X = ancho_x; dwPos.Y = alto_y; SetConsoleCursorPosition(hcon, dwPos); } int main() { // Configura consola. ConfigurarConsola(); // Inicializa el puerto serie. Serial* Puerto = new Serial("COM2"); if (!Puerto->IsConnected()) { cerr << "Error al conectar con el puerto serie." << endl; delete Puerto; return 1; } // Comandos para Arduino. char Luz_ON[] = "Luz_ON"; // Envía "Luz_ON" al puerto serie. char Luz_OFF[] = "Luz_OFF"; char Salir[] = "Salir"; char lectura[50] = { 0 }; // Guardan datos de entrada del puerto leído. //int tecla; // Guarda un 1 ó 2 tipo entero que introduces desde la consola. cout << "Pulse 1 para encender el Led, pulse 2 para apagar. (Ctrl+C para salir)" << endl; while (true) { // Detecta si se ha pulsado una tecla. Desde que pulse una tecla, automáticamente envía el comando. // ¿Has pulsado la tecla 1 ó 1 extendido? if (GetAsyncKeyState('1') & 0x8000 || GetAsyncKeyState(VK_NUMPAD1) & 0x8000) // Si se presiona '1' o 'Numpad 1'. { // Sí. Envía este comando. cout << "Enviando: " << Luz_ON << endl; Puerto->WriteData(Luz_ON, strlen(Luz_ON)); Sleep(500); // Espera un momento para evitar múltiples envíos. } if (GetAsyncKeyState('2') & 0x8000 || GetAsyncKeyState(VK_NUMPAD2) & 0x8000) // Si se presiona '2' o 'Numpad 2'. { cout << "Enviando: " << Luz_OFF << endl; Puerto->WriteData(Luz_OFF, strlen(Luz_OFF)); Sleep(500); // Espera un momento para evitar múltiples envíos. } if (GetAsyncKeyState('3') & 0x8000 || GetAsyncKeyState(VK_NUMPAD3) & 0x8000) { cout << "Enviando: " << Salir << endl; Puerto->WriteData(Salir, strlen(Salir)); Sleep(500); // Espera un momento para evitar múltiples envíos. } // Lee datos del puerto serie. int n = Puerto->ReadData(lectura, sizeof(lectura) - 1); // Recibe datos del puerto serie. if (n > 0) { lectura[n] = '\0'; // Finaliza la cadena. cout << "Recibido: " << lectura << endl; cout << "-------------------" << endl; } Sleep(100); // Reduce la carga de CPU. } delete Puerto; // Libera memoria. return 0; }
Saludos.
|
|
|
5
|
Programación / Programación C/C++ / ERROR C2665 'Serial::Serial':ninguna función sobrecargada pudo convertir todos los tipos de argumento
|
en: 27 Octubre 2024, 00:02 am
|
Buenas. Este es el código que me da error probándolo con Visual Studio 2022 de C++ nativo. Gravedad Código Descripción Proyecto Archivo Línea Estado suprimido Detalles Error (activo) E0289 ninguna instancia del constructor "Serial::Serial" coincide con la lista de argumentos Arduino y puerto serie CPP Consola 01 D:\Visual Studio 2022\Arduino y puerto serie CPP Consola 01\Arduino y puerto serie CPP Consola 01\Arduino y puerto serie CPP Consola 01.cpp 56 Gravedad Código Descripción Proyecto Archivo Línea Estado suprimido Detalles Error C2665 'Serial::Serial':ninguna función sobrecargada pudo convertir todos los tipos de argumento Arduino y puerto serie CPP Consola 01 D:\Visual Studio 2022\Arduino y puerto serie CPP Consola 01\Arduino y puerto serie CPP Consola 01\Arduino y puerto serie CPP Consola 01.cpp 56 /* Para crear conexión con los puertos COM1 - COM9. Serial* Arduino = new Serial("COM7"); Para crear conexión con los puertos COM10 en adelante. Serial* Arduino = new Serial("\\\\.\\COM10"); */ #include <iostream> #include <fstream> #include <windows.h> // Para mostrar texto en el título de la ventana. #include <stdio.h> // Cambio color de fondo y letras. #include "SerialClass.h" using namespace std; //using std::cout; //using std::cin; // Función posición del cursor. void gotoxy(int ancho_x, int alto_y) { HANDLE hcon; hcon = GetStdHandle(STD_OUTPUT_HANDLE); COORD dwPos{}; dwPos.X = ancho_x; dwPos.Y = alto_y; SetConsoleCursorPosition(hcon, dwPos); } int main() { #pragma region "Configuración ventana." // Mostrar caracteres correctamente en pantalla y título de la ventana. SetConsoleOutputCP(65001); wchar_t titulo[128]; MultiByteToWideChar(CP_UTF8, 0, "Arduino puerto serie - C++ nativo", -1, titulo, 128); SetConsoleTitleW(titulo); // Tamaño de la pantalla. Se cambia en los dos últimos dígitos. SMALL_RECT r = { 0, 0, 120, 40 }; // X = 80, Y = 20. SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &r); // Cambio color de 6 (amarillo / naranja), color letras 0 (negro). system("color 60"); // Ocultar cursor. CONSOLE_CURSOR_INFO cci; GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci); cci.bVisible = 0; // 0 oculta. 1 muestra cursor. SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci); #pragma endregion // Puerto serie. Serial* Puerto = new Serial("COM3"); // Comandos para Arduino. char Luz_ON[] = "Luz_ON"; // Envía "Luz_ON" al puerto serie. char Luz_OFF[] = "Luz_OFF"; char lectura[50] = "\0"; // Guardan datos de entrada del puerto. int opc; // Guarda un 1 o 2 tipo entero queintroduces desde la consola. while (Puerto->IsConnected()) { cout << endl; // Retorno. cout << "Introduzca la opcion deseada: " << endl; cout << "Pulse 1 para encender el Led, pulse 2 para apagar." << endl << endl; // Muestra texto en pantalla. cin >> opc; // Aquí introduces un número, el 1 o el 2. switch (opc) // Espera recibir un 1 o un 2. { case 1: // Encener luz. cout << "Enviando: " << Luz_ON << endl; // Muestra en pantalla textos. Puerto->WriteData(Luz_ON, sizeof(Luz_ON) - 1); // Envía al puerto el texto "Luz_ON". break; case 2: // Apagar luz. cout << "Enviando: " << Luz_OFF << endl; Puerto->WriteData(Luz_OFF, sizeof(Luz_OFF) - 1); break; default: // Si haz pulsado otro número distinto del 1 y 2, muestra cout << "Puse del 1 al 2."; // este mensaje. } Sleep(500); int n = Puerto->ReadData(lectura, 49); // Recibe datos del puerto serie. if (n > 0) { lectura[n + 1] = '\0'; // Limpia de basura la variable. cout << "Recibido: " << lectura << endl; // Muestra en pantalla dato recibido. cout << "-------------------" << endl; } cin.ignore(256, '\n'); // Limpiar buffer del teclado. } }
¿Alguna idea? Saludos.
|
|
|
7
|
Programación / .NET (C#, VB.NET, ASP) / Salir de un void
|
en: 28 Agosto 2024, 23:20 pm
|
Buenas: A veces entro en una función void, como que se llama así mismo y el programa no funciona como debería. En la pila de llamadas muestra esto. Ver zoom. Como puedes ver en la imagen en la Pila de llamadas, cada vez que intento salir del submenú, se repite cada vez más y en este caso hay tres, Volumen() y otras tres AjustesPrincipal(). Tiene que salir desde que salga, no que tenga comportamiento de este tipo. Dejo código por si les dice algo en C# en modo consola. Volumen();// ** VOLUMEN ** //> Vol: ■■■■■■-- 6 // //> ATRÁS > INICIO using LCD_Menu_con_submenus_Consola_03.Ventana01; using System; namespace LCD_Menu_con_submenus_Consola_03.Ventana03 { public class _0_Volumen { static int volumen = 6; public static void Volumen() { // Variables. string[] TEXTO = { " ** VOLUMEN ** ", // Posición 0. " Vol: ", // 1 "■", // 2 "-", // 3 "ATRÁS", // 4 "INICIO", // 5 ">", // 6 " " // 7 }; const int VOLMEN_MAX = 8; int opcion = 0; // 0 = Volumen, 1 = ATRÁS y 2 = INICIO. ConsoleKey teclaVolumen; // Limpiar pantalla. Console.Clear(); // Mostrar menú. MostrarMenu(); do { // ¿Están en la opción Volumen o 0? if (opcion == 0) { // Sí. Mostrar volumen. MostrarVolumen(); } // Captura tecla y lo guarda en la variable teclaVolumen. teclaVolumen = Console.ReadKey(true).Key; // ¿Están en la opción Volumen o 0? if (opcion == 0) { // Sí. Controlar el volumen. if ((teclaVolumen == ConsoleKey.RightArrow) && (volumen < VOLMEN_MAX)) { volumen++; } else if ((teclaVolumen == ConsoleKey.LeftArrow) && (volumen > 0)) { volumen--; } else if ((teclaVolumen == ConsoleKey.UpArrow) || (teclaVolumen == ConsoleKey.DownArrow)) { opcion = 1; // 1 = ATRÁS. } } else // No. Mientras. { // Navegar entre ATRÁS e INICIO. if ((teclaVolumen == ConsoleKey.LeftArrow) && (opcion == 2)) { opcion = 1; // 1 = ATRÁS. } else if ((teclaVolumen == ConsoleKey.RightArrow) && (opcion == 1)) { opcion = 2; // 2 = INICIO. } else if ((teclaVolumen == ConsoleKey.UpArrow) || (teclaVolumen == ConsoleKey.DownArrow)) { opcion = 0; // 0 = Volumen. } } // Mostrar menú. MostrarMenu(); } while (teclaVolumen != ConsoleKey.Enter || opcion == 0)); // Acción al pulsar Enter. if (opcion == 1) { // ATRÁS. _0_Ajustes.AjustesPrincipal(); } else if (opcion == 2) { // INICIO. Inicio.InicioPrincipal(); } // Mostrar dibujado en pantalla. void MostrarVolumen() { Console.SetCursorPosition(0, 0); Console.Write(TEXTO[0]); // ** VOLUMEN ** Console.SetCursorPosition(1, 1); Console.Write(TEXTO[1]); // Vol: for (int i = 0; i < volumen; i++) { Console.Write(TEXTO[2]); // ■ } for (int j = 0; j < (VOLMEN_MAX - volumen); j++) { Console.Write(TEXTO[3]); // - } // Mostrar el volumen en número. Console.SetCursorPosition(16, 1); Console.Write(volumen); } void MostrarMenu() { Console.SetCursorPosition(2, 3); Console.Write(TEXTO[4]); // ATRÁS Console.SetCursorPosition(13, 3); Console.Write(TEXTO[5]); // INICIO Console.SetCursorPosition(0, 1); Console.Write(TEXTO[7]); // Console.SetCursorPosition(0, 3); Console.Write(TEXTO[7]); // Console.SetCursorPosition(11, 3); Console.Write(TEXTO[7]); // // ¿Es 0 = Volumen? if (opcion == 0) { // Sí. Indica esta posición del cursor. Console.SetCursorPosition(0, 1); } // No. Entonces, ¿ 1 = ATRÁS? else if (opcion == 1) { // Sí. Indica esta posición del cursor. Console.SetCursorPosition(0, 3); } // No. Entonces, ¿2 = INICIO? else if (opcion == 2) { // Sí. Indica esta posición del cursor. Console.SetCursorPosition(11, 3); } // Muestra el caracter >. Console.Write(TEXTO[6]); // > } } } }
AjustesPrincipal():// ** AJUSTES ** // > Volumen. // Brillo/Contraste // [x] Beep. // ** AJUSTES ** // > [x] Luz de fondo. // ATRÁS // INICIO using LCD_Menu_con_submenus_Consola_03.Ventana03; using System; namespace LCD_Menu_con_submenus_Consola_03.Ventana01 { public class _0_Ajustes { public static void AjustesPrincipal() { string[] TEXTO = { " ** AJUSTES ** ", // Posición 0. " Volumen. ", // 1 " Brillo / Contraste", // 2 " [ ] Beep ", // 3 " [ ] Luz de fondo. ", // 4 " ATRÁS ", // 5 " INICIO ", // 6 ">", // 7 "x", // 8 " " // 9 }; // Contador de teclas y navegador. sbyte indiceSeleccionado = 0; // Índice seleccionado de cada opción del menú. bool salir = false; // Para salir del menú principal al INICIO. const sbyte SELECCION_OPCIONES_TOTALES = 5; // Total de opciones para seleccionar y fija. // Capturar tecla para luego validar. ConsoleKey tecla; do { //****************************************************************** // Dibujo el menú principal. switch (indiceSeleccionado) { case 0: Console.SetCursorPosition(0, 0); Console.Write(TEXTO[0]); // ** AJUSTES ** Console.SetCursorPosition(0, 1); Console.Write(TEXTO[1]); // > Volumen. Console.SetCursorPosition(0, 1); Console.Write(TEXTO[7]); // > Console.SetCursorPosition(0, 2); Console.Write(TEXTO[2]); // Brillo / Contraste Console.SetCursorPosition(0, 3); Console.Write(TEXTO[3]); // [ ] Beep. break; case 1: Console.SetCursorPosition(0, 0); Console.Write(TEXTO[0]); // ** AJUSTES ** Console.SetCursorPosition(0, 1); Console.Write(TEXTO[1]); // Volumen. Console.SetCursorPosition(0, 2); Console.Write(TEXTO[2]); // > Brillo / Contraste Console.SetCursorPosition(0, 2); Console.Write(TEXTO[7]); // > Console.SetCursorPosition(0, 3); Console.Write(TEXTO[3]); // [ ] Beep. break; case 2: Console.SetCursorPosition(0, 0); Console.Write(TEXTO[0]); // ** AJUSTES ** Console.SetCursorPosition(0, 1); Console.Write(TEXTO[1]); // Volumen. Console.SetCursorPosition(0, 2); Console.Write(TEXTO[2]); // Brillo / Contraste Console.SetCursorPosition(0, 3); Console.Write(TEXTO[3]); // > [ ] Beep. Console.SetCursorPosition(0, 3); Console.Write(TEXTO[7]); // > break; case 3: Console.SetCursorPosition(0, 0); Console.Write(TEXTO[0]); // ** AJUSTES ** Console.SetCursorPosition(0, 1); Console.Write(TEXTO[4]); // > [ ] Luz de fondo. Console.SetCursorPosition(0, 1); Console.Write(TEXTO[7]); // > Console.SetCursorPosition(0, 2); Console.Write(TEXTO[5]); // ATRÁS Console.SetCursorPosition(0, 3); Console.Write(TEXTO[6]); // INICIO break; case 4: Console.SetCursorPosition(0, 0); Console.Write(TEXTO[0]); // ** AJUSTES ** Console.SetCursorPosition(0, 1); Console.Write(TEXTO[4]); // [ ] Luz de fondo. Console.SetCursorPosition(0, 2); Console.Write(TEXTO[5]); // > ATRÁS Console.SetCursorPosition(0, 2); Console.Write(TEXTO[7]); // > Console.SetCursorPosition(0, 3); Console.Write(TEXTO[6]); // INICIO break; case 5: Console.SetCursorPosition(0, 0); Console.Write(TEXTO[0]); // ** AJUSTES ** Console.SetCursorPosition(0, 1); Console.Write(TEXTO[4]); // [ ] Luz de fondo. Console.SetCursorPosition(0, 2); Console.Write(TEXTO[5]); // ATRÁS Console.SetCursorPosition(0, 3); Console.Write(TEXTO[6]); // > INICIO Console.SetCursorPosition(0, 3); Console.Write(TEXTO[7]); // > break; default: Console.Write("Fuera de rango. "); break; } // Fin de pintar el menú principal. //****************************************************************** // Leer tecla ingresada por el usuario. tecla = Console.ReadKey(true).Key; // Validar el tipo de tecla. if (tecla == ConsoleKey.Enter) { switch (indiceSeleccionado) { case 0: _0_Volumen.Volumen(); break; case 1: break; case 2: break; case 3: break; case 4: salir = true; break; case 5: Inicio.InicioPrincipal(); break; default: Console.Write("Fuera de rango. "); break; } } // ¿Has pulsado tecla flecha Abajo? if (tecla == ConsoleKey.DownArrow) { indiceSeleccionado++; } // Entonces si pulsas tecla flecha Arriba. if (tecla == ConsoleKey.UpArrow) { indiceSeleccionado--; } // Si está en la última opción, salta a la primera. if (indiceSeleccionado > SELECCION_OPCIONES_TOTALES) { indiceSeleccionado = 0; } // Si está en la primera posición, salta a la última. if (indiceSeleccionado < 0) { indiceSeleccionado = SELECCION_OPCIONES_TOTALES; } // Salida del menú. } while (salir == false); } } }
Llevo tiempo sin resolver esto. Espero que se entienda lo que quiero decir, si no, se lo explico con más capturas. Muchas gracias.
|
|
|
8
|
Programación / .NET (C#, VB.NET, ASP) / Guardar y leer archivo de texto
|
en: 8 Agosto 2024, 02:48 am
|
Buenas:  Usando C# en modo consola, se puede señalar con las flechas del teclado seleccionar alguna opción con esto >. Solo debe estar marcado con una x. La idea es, al ejecutar el programa, si no encuentra el archivo.txt, lo cree y escribe la opción marcada con la x. Al volver a ejecutar el programa, me indica la opción marcada que leyó en el archivo.txt. Código que he hecho hasta ahora pero no lee, si lo crea es este: using System; using System.IO; namespace Pruebas_Opciones_Consola_02 { internal class Program { static void Main(string[] args) { #region Configuración ventana. // Título de la ventana. Console.Title = "Opciones"; // Tamaño de la ventana, x, y o, ancho y alto. const byte ancho = 20, alto = 5; Console.SetWindowSize(ancho, alto); // Quitar scroll laterales. Derecho y abajo. Console.SetBufferSize(ancho, alto); // Color de fondo. Console.BackgroundColor = ConsoleColor.Yellow; // Color de las letras. Console.ForegroundColor = ConsoleColor.Black; // Limpiar pantalla y dejarlo todo en color de fondo. Console.Clear(); // Visible el cursor. // No! Así lo haces invisible. Console.CursorVisible = false; #endregion string[] opciones = { " ** TÍTULO ** ", // Posición 0. " ( ) Opción A ", // 1 " ( ) Opción B ", // 2 " ( ) Opción C ", // 3 " SALIR ", // 4 ">", // 5 "x", // 6 " ", // 7 " " // 8 }; // Cada vez que se vuelva al menú, está señalizado con la x. int itemSeleccionado; Menu(); #region Opociones, selecciones y guardar archivo .txt void OpcionesA() { Console.SetCursorPosition(0, 0); Console.Write(opciones[0]); // ** TÍTULO ** Console.SetCursorPosition(0, 1); Console.Write(opciones[1]); // ( ) Opción A Console.SetCursorPosition(0, 2); Console.Write(opciones[2]); // ( ) Opción B Console.SetCursorPosition(0, 3); Console.Write(opciones[3]); // ( ) Opción C } void OpcionesB() { Console.SetCursorPosition(0, 1); Console.Write(opciones[4]); // SALIR Console.SetCursorPosition(0, 2); Console.Write(opciones[8]); // Console.SetCursorPosition(0, 3); Console.Write(opciones[8]); // } void SelectorA() { Console.SetCursorPosition(0, 1); Console.Write(opciones[5]); // > Console.SetCursorPosition(0, 2); Console.Write(opciones[7]); Console.SetCursorPosition(0, 3); Console.Write(opciones[7]); } void SelectorB() { Console.SetCursorPosition(0, 1); Console.Write(opciones[7]); Console.SetCursorPosition(0, 2); Console.Write(opciones[5]); // > Console.SetCursorPosition(0, 3); Console.Write(opciones[7]); } void SelectorC() { Console.SetCursorPosition(0, 1); Console.Write(opciones[7]); Console.SetCursorPosition(0, 2); Console.Write(opciones[7]); Console.SetCursorPosition(0, 3); Console.Write(opciones[5]); // > } #endregion void Menu() { sbyte indiceSeleccionado = 0; // Índice seleccionado de cada opción del menú. bool salir = false; // Para salir del menú principal al INICIO. sbyte SELECCION_OPCIONES_TOTALES = 3; // Total de opciones para seleccionar y fija. string opA = "x"; string opB = " "; string opC = " "; // Capturar tecla para luego validar. ConsoleKey tecla; itemSeleccionado = 1; // Crear archivo y guarda el * seleccioinado en él. if (File.Exists("Archivo.txt")) { string data = File.ReadAllText("Archivo.txt"); itemSeleccionado = Convert.ToInt32(data); //itemSeñalado = itemSeleccionado; } do { //****************************************************************** // Dibujo el menú principal. switch (indiceSeleccionado) { case 0: OpcionesA(); SelectorA(); Console.SetCursorPosition(3, 1); Console.Write(opA); Console.SetCursorPosition(3, 2); Console.Write(opB); Console.SetCursorPosition(3, 3); Console.Write(opC); break; case 1: OpcionesA(); SelectorB(); Console.SetCursorPosition(3, 1); Console.Write(opA); Console.SetCursorPosition(3, 2); Console.Write(opB); Console.SetCursorPosition(3, 3); Console.Write(opC); break; case 2: OpcionesA(); SelectorC(); Console.SetCursorPosition(3, 1); Console.Write(opA); Console.SetCursorPosition(3, 2); Console.Write(opB); Console.SetCursorPosition(3, 3); Console.Write(opC); break; case 3: OpcionesB(); Console.SetCursorPosition(0, 1); Console.Write(opciones[5]); // > break; default: Console.Write("Fuera de rango. "); break; } // Fin de pintar el menú principal. //****************************************************************** // Leer tecla ingresada por el usuario. tecla = Console.ReadKey(true).Key; // Validar el tipo de tecla. if (tecla == ConsoleKey.Enter) { switch (indiceSeleccionado) { case 0: opA = "x"; opB = " "; opC = " "; break; case 1: opA = " "; opB = "x"; opC = " "; break; case 2: opA = " "; opB = " "; opC = "x"; break; case 3: indiceSeleccionado = 0; // Restaurar índice antes de salir. salir = true; // Salir. break; default: Console.Write("Fuera de rango. "); break; } } // ¿Has pulsado tecla flecha Abajo? if (tecla == ConsoleKey.DownArrow) { indiceSeleccionado++; } // Entonces si pulsas tecla flecha Arriba. if (tecla == ConsoleKey.UpArrow) { indiceSeleccionado--; } // Si está en la última opción, salta a la primera. if (indiceSeleccionado > SELECCION_OPCIONES_TOTALES) { indiceSeleccionado = 0; } // Si está en la primera posición, salta a la última. if (indiceSeleccionado < 0) { indiceSeleccionado = SELECCION_OPCIONES_TOTALES; } // Uso la tecla escape como salida. } while (!salir); } } } }
El código es malo, fácil de entender, mientras funcione... todo bien. Gracias.
|
|
|
9
|
Programación / .NET (C#, VB.NET, ASP) / Cambiar resolución en pantalla
|
en: 7 Agosto 2024, 00:38 am
|
Hola: Tengo esta resolución en pantalla de 20x5.  Quiero hacerlo como muestra abajo, lo logro pulsando la tecla Control y muevo la rueda del ratón. Como puedes ver, cambia el tamaño de la ventana más las letras de su contenido de la ventana.  Si lo programo, me muestra la resolución igual pero las letras pequeñas como indica abajo.  El código base es este en C# consola. using System; namespace Resolucion_y_tamaño_ventana_Consola_01 { internal class Program { static void Main(string[] args) { // Título de la ventana. Console.Title = "Ventana C#"; // Tamaño de la ventana, x, y o, ancho y alto. const byte ancho = 77; const byte alto = 25; Console.SetWindowSize(ancho, alto); // Quitar scroll laterales, derecho y abajo. Console.SetBufferSize(ancho, alto); // Cursor invisible. Console.CursorVisible = false; Console.Write("Resolución 20 x 4."); // Pulse cualquier tecla para salir. Console.ReadKey(); } } }
La pregunta. ¿Se puede programar como en la segunda imagen? Es decir, a parte de subir la resolución de pantalla que eso si se puede, aumentar el tamaño de las letras de la consola. Muchas gracias por leer hasta aquí. 
|
|
|
10
|
Programación / .NET (C#, VB.NET, ASP) / Intentar diseñar bien
|
en: 30 Julio 2024, 01:11 am
|
Buenas: Como se aprecia esta imagen, está marcada la primera opción con una x.  Quiero hacer que nada más ejecutar el programa, se refleje esa x, ya que está simulando un radioButton en modo consola. Si pulsas cualquiera de las tres opciones una x, las demás si tiene alguna, se quita, solo queda una sola seleccionada. Al pulsar Enter por ejemplo > (x) Voltios, luego se me borra porque vuelve otra vez e redibujado principal. Dejo aquí el código porque no se en que fallo. Lenguaje C#. // ** P1 ** // > (x) % // ( ) Voltios // ( ) Decimal 0-1023 // ** P1 ** // > ATRÁS // GUARDAR using System; namespace LCD_Menu_con_submenus_Consola_03.Ventana02 { public class _0_P1 { #region Variables. // Contador de teclas y navegador. static sbyte indiceSeleccionado = 0; // Índice seleccionado de cada opción del menú. static bool salir = false; // Para salir del menú principal al INICIO. const sbyte SELECCION_OPCIONES_TOTALES = 3; // Total de opciones para seleccionar y fija. public static readonly string[] TEXTO = new string[] { " ** P1 ** ", // Posición 0. " ( ) % ", // 1 " ( ) Voltios ", // 2 " ( ) Decimal 0-1023", // 3 " SALIR ", // 4 " ", // 5 ">", // 6 "x" // 7 }; #endregion public static void P1_Principal() { // Capturar tecla para luego validar. ConsoleKey tecla; // Limpiar pantalla. Console.Clear(); do { //****************************************************************** // Dibujo el menú principal. switch (indiceSeleccionado) { case 0: Console.SetCursorPosition(0, 0); Console.Write(TEXTO[0]); // ** P1 ** Console.SetCursorPosition(0, 1); Console.Write(TEXTO[1]); // > ( ) % Console.SetCursorPosition(0, 1); Console.Write(TEXTO[6]); // > Console.SetCursorPosition(0, 2); Console.Write(TEXTO[2]); // ( ) Voltios Console.SetCursorPosition(0, 3); Console.Write(TEXTO[3]); // ( ) Decimal 0-1023 break; case 1: Console.SetCursorPosition(0, 0); Console.Write(TEXTO[0]); // ** P1 ** Console.SetCursorPosition(0, 1); Console.Write(TEXTO[1]); // ( ) % Console.SetCursorPosition(0, 2); Console.Write(TEXTO[2]); // > ( ) Voltios Console.SetCursorPosition(0, 2); Console.Write(TEXTO[6]); // > Console.SetCursorPosition(0, 3); Console.Write(TEXTO[3]); // ( ) Decimal 0-1023 break; case 2: Console.SetCursorPosition(0, 0); Console.Write(TEXTO[0]); // ** P1 ** Console.SetCursorPosition(0, 1); Console.Write(TEXTO[1]); // ( ) % Console.SetCursorPosition(0, 2); Console.Write(TEXTO[2]); // ( ) Voltios Console.SetCursorPosition(0, 3); Console.Write(TEXTO[3]); // > ( ) Decimal 0-1023 Console.SetCursorPosition(0, 3); Console.Write(TEXTO[6]); // > break; case 3: Console.SetCursorPosition(0, 0); Console.Write(TEXTO[0]); // ** P1 ** Console.SetCursorPosition(0, 1); Console.Write(TEXTO[4]); // > SALIR Console.SetCursorPosition(0, 1); Console.Write(TEXTO[6]); // > Console.SetCursorPosition(0, 2); Console.Write(TEXTO[5]); // Console.SetCursorPosition(0, 3); Console.Write(TEXTO[5]); // break; default: Console.Write("Fuera de rango. "); break; } // Fin de pintar el menú principal. //****************************************************************** // Leer tecla ingresada por el usuario. tecla = Console.ReadKey(true).Key; // Validar el tipo de tecla. if (tecla == ConsoleKey.Enter) { switch (indiceSeleccionado) { case 0: Console.SetCursorPosition(3, 1); Console.Write(TEXTO[7]); // x break; case 1: Console.SetCursorPosition(3, 2); Console.Write(TEXTO[7]); // x break; case 2: Console.SetCursorPosition(3, 3); Console.Write(TEXTO[7]); // x break; case 3: salir = true; // Salir break; default: Console.Write("Fuera de rango. "); break; } } // ¿Has pulsado tecla flecha Abajo? else if (tecla == ConsoleKey.DownArrow) { indiceSeleccionado++; } // Entonces si pulsas tecla flecha Arriba. else if (tecla == ConsoleKey.UpArrow) { indiceSeleccionado--; } // Si está en la última opción, salta a la primera. if (indiceSeleccionado > SELECCION_OPCIONES_TOTALES) { indiceSeleccionado = 0; } // Si está en la primera posición, salta a la última. if (indiceSeleccionado < 0) { indiceSeleccionado = SELECCION_OPCIONES_TOTALES; } // Uso la tecla escape como salida. } while (!salir); } } }
Saludos.
|
|
|
|
|
|
|