Hacer funcionar simulador lavadora

Iniciado por Meta, 6 Marzo 2021, 17:39 PM

0 Miembros y 1 Visitante están viendo este tema.

Meta



Ver imagen.

Este proyecto ya es un reto para muchos, jajajja, aún así se puede intentar.

Aquí tengo un simulador de lavadora, puedes controlar el giro del tambor o motor, velocidad, nivel de agua. Es totalmente funcional.

Hay en este caso aunque si funciona, quiero ignorarlo para el próximo programa, Giro del motor.

La mejora o el próximo programa funciona desde el puerto serie sin usar ningún trackBar.

trackBar_Velocidad_motor funciona los valores como máximo a 100 y mínimo a 0.

trackBar_Nivel_de_agua funciona los valores como máximo a 90 y mínimo a -90.

Los sustitutos del trackBar son datos que llegan desde el puerto serie, algo así como esto, por ejemplo:

Código (csharp) [Seleccionar]
50, 80

El ejemplo de arriba indica el número 50, que varía de 0 a 100, la velocidad. El 80 es el caso del 90 a -90 del nivel de agua.

Esos datos si quiero que esté. Puede recibir datos a 9600 baudios y por cada 1000 milisegundos, o lo que es lo mismo, a cada segundo.

El código completo de este programa con trackBar es este.
Código (csharp) [Seleccionar]
/*
Te explico la formula

float fDeltaAngulo = (((nRPM * 360) / (60 * 1000)) * timer.Interval) * ((float)trackBar_Velocidad_motor.Value / (float)trackBar_Velocidad_motor.Maximun)

   1. (nRPM * 360) -> Grados por minuto.
   2. (60 * 1000) -> Milisegundos por minuto.
   3. ((nRPM * 360) / (60 * 1000)) -> Grados por milisegundo.
   4. (((nRPM * 360) / (60 * 1000)) * timer.Interval) -> Grados por tick del timer.
   5.  ((float)trackBar_Velocidad_motor.Value / (float)trackBar_Velocidad_motor.Maximun) -> Porcentaje de la velocidad.
   6. (((nRPM * 360) / (60 * 1000)) * timer.Interval) * ((float)trackBar_Velocidad_motor.Value / (float)trackBar_Velocidad_motor.Maximun) -> Calcula los grados por tick del timer aplicando un porcentaje.

Según esta formula, si el trackbar esta en 0, grados por tick * 0 = 0 (esta parado), si el trackbar esta al maximo, grados por tick * 1 = grados por tick (el angulo aumenta al máximo).
*/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Lavadora_05
{
    public partial class Form1 : Form
    {
        // Variables.
        private Pen lápiz2;
        private Pen lápiz3;
        private Pen lápiz4;
        private float angulo;
        private SolidBrush agua;

        private GraphicsPath m_lavadora;
        private GraphicsPath m_agua;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Text = "Simulador lavadora";
            pictureBox1.Size = new Size(300, 300);
            pictureBox1.BackColor = Color.LightGray;

            lápiz2 = new Pen(Color.DarkGray, 10);
            lápiz2.StartCap = LineCap.ArrowAnchor;
            lápiz2.EndCap = LineCap.RoundAnchor;

            lápiz3 = new Pen(Color.Black, 5);
            lápiz4 = new Pen(Color.Gray, 10);

            angulo = 0;

            agua = new SolidBrush(Color.FromArgb(200, 0, 155, 219)); // Transparencia del agua 200.
            trackBar_Nivel_de_agua.Value = -90; // Para que empiece sin agua.
        }

        // Dibuja y colorea.
        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawRectangle(lápiz3, 10, 10, pictureBox1.ClientSize.Width - 20, pictureBox1.ClientSize.Height - 20);
            e.Graphics.DrawEllipse(lápiz4, 10, 10, pictureBox1.ClientSize.Height - 20, pictureBox1.ClientSize.Height - 20);

            e.Graphics.TranslateTransform(pictureBox1.ClientSize.Width / 2, pictureBox1.ClientSize.Height / 2);
            e.Graphics.RotateTransform(angulo);
            e.Graphics.TranslateTransform(-pictureBox1.ClientSize.Width / 2, -pictureBox1.ClientSize.Height / 2);
            //e.Graphics.DrawLine(lápiz2, 20, pictureBox1.ClientSize.Height / 2, pictureBox1.ClientSize.Width / 2, pictureBox1.ClientSize.Height / 2);
            e.Graphics.DrawPath(lápiz2, m_lavadora);
            e.Graphics.ResetTransform();
            e.Graphics.FillPath(agua, m_agua);
        }

        // Refresca el valor actual.
        private void trackBar_Giro_del_motor_ValueChanged(object sender, EventArgs e)
        {
            angulo = (float)trackBar_Giro_del_motor.Value;
            pictureBox1.Refresh();
        }

        // Cambia el tamaño del control.
        private void pictureBox1_Resize(object sender, EventArgs e)
        {
            int ancho = pictureBox1.ClientSize.Width;
            int alto = pictureBox1.ClientSize.Height;

            m_lavadora = new GraphicsPath();

            m_lavadora.AddEllipse(20, 20, ancho - 40, alto - 40);
            m_lavadora.CloseFigure();
            m_lavadora.AddLine(20, (alto / 2), ancho - 20, (alto / 2));
            m_lavadora.CloseFigure();
            m_lavadora.AddLine(ancho / 2, 20, ancho / 2, alto - 20);
            m_lavadora.CloseFigure();

            m_agua = new GraphicsPath();

            m_agua.AddArc(20, 20, ancho - 40, alto - 40, trackBar_Nivel_de_agua.Value, 180 - 2 * trackBar_Nivel_de_agua.Value);
            m_agua.CloseFigure();
        }

        private void trackBar_Nivel_de_agua_ValueChanged(object sender, EventArgs e)
        {
            m_agua = new GraphicsPath();

            m_agua.AddArc(20, 20, pictureBox1.ClientSize.Width - 40, pictureBox1.ClientSize.Height - 40, -trackBar_Nivel_de_agua.Value, 180 - 2 * -trackBar_Nivel_de_agua.Value);
            m_agua.CloseFigure();
            pictureBox1.Refresh();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //60 vueltas por minuto
            float nRPM = 60;

            float fDeltaAngulo = (((nRPM * 360) / (60 * 1000)) * (float)timer1.Interval) * ((float)trackBar_Velocidad_motor.Value / (float)trackBar_Velocidad_motor.Maximum);
            float track = (float)trackBar_Velocidad_motor.Value;
            angulo += fDeltaAngulo;
            label_angulo.Text = "angulo " + angulo.ToString();
            label_fDeltaAngulo.Text = "fDeltaAngulo " + fDeltaAngulo.ToString();
            pictureBox1.Refresh();

        }

        private void button_Empezar_Click(object sender, EventArgs e)
        {
            timer1.Start();
            //timer1.Enabled = true; // También válido.
        }

        private void button_parar_Click(object sender, EventArgs e)
        {
            timer1.Stop();
            //timer1.Enabled = false; // También válido.
        }
    }
}


El código que he intentado es este pero no funciona ni una parte y está incompleto.

Código (csharp) [Seleccionar]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Lavadora_07
{
    public partial class Form1 : Form
    {
        // Utilizaremos un string-builder como búfer auxiliar.
        // La trama llegará fragmentada.
        StringBuilder sb;

        // Nuestro delegado recibe como argumento el string con la trama.
        readonly Action<string> NuevaTrama;

        // Variables.
        private Pen lápiz2;
        private Pen lápiz3;
        private Pen lápiz4;
        private float angulo;
        private SolidBrush agua;

        private GraphicsPath m_lavadora;
        private GraphicsPath m_agua;

        // Variables sustituto del trackBar.
        private int trackBar_Nivel_de_agua = 0;
        private int trackBar_Velocidad_motor = 0;

        public Form1()
        {
            InitializeComponent();

            sb = new StringBuilder();
            NuevaTrama = Actualizar;
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            // Añado los puertos disponible en el PC con SerialPort.GetPortNames() al comboBox_Puerto.
            try
            {
                comboBox_Puerto.DataSource = SerialPort.GetPortNames();
            }

            catch
            {
                MessageBox.Show("No encuentra ningún puerto físico ni virtual.", "Aviso:",
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

            // Añado los puertos disponible en el PC con SerialPort.GetPortNames() al comboBox_Puerto.
            comboBox_Puerto.DataSource = SerialPort.GetPortNames();

            // // Añade puertos disponibles físicos  y virtuales.
            serialPort1.PortName = comboBox_Puerto.Text.ToString();

            serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);

            // Dibujo tambor lavadora.
            pictureBox1.Size = new Size(300, 300);
            pictureBox1.BackColor = Color.LightGray;

            lápiz2 = new Pen(Color.DarkGray, 10);
            lápiz2.StartCap = LineCap.ArrowAnchor;
            lápiz2.EndCap = LineCap.RoundAnchor;

            lápiz3 = new Pen(Color.Black, 5);
            lápiz4 = new Pen(Color.Gray, 10);

            angulo = 0;

            agua = new SolidBrush(Color.FromArgb(200, 0, 155, 219)); // Transparencia del agua 200.
            trackBar_Nivel_de_agua = -90; // Para que empiece sin agua.
        }

        // Detecta USB o puerto serie virtual cuando lo conecta y desconecta del cable.
        protected override void WndProc(ref Message USB)
        {
            if (USB.Msg == 0x219)
            {
                comboBox_Puerto.DataSource = SerialPort.GetPortNames();
            }

            base.WndProc(ref USB); // Detecta si hay cambios en el usb y si los hay los refleja.
        }

        // Dibuja y colorea.
        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawRectangle(lápiz3, 10, 10, pictureBox1.ClientSize.Width - 20, pictureBox1.ClientSize.Height - 20);
            e.Graphics.DrawEllipse(lápiz4, 10, 10, pictureBox1.ClientSize.Height - 20, pictureBox1.ClientSize.Height - 20);

            e.Graphics.TranslateTransform(pictureBox1.ClientSize.Width / 2, pictureBox1.ClientSize.Height / 2);
            e.Graphics.RotateTransform(angulo);
            e.Graphics.TranslateTransform(-pictureBox1.ClientSize.Width / 2, -pictureBox1.ClientSize.Height / 2);
            //e.Graphics.DrawLine(lápiz2, 20, pictureBox1.ClientSize.Height / 2, pictureBox1.ClientSize.Width / 2, pictureBox1.ClientSize.Height / 2);
            e.Graphics.DrawPath(lápiz2, m_lavadora);
            e.Graphics.ResetTransform();
            e.Graphics.FillPath(agua, m_agua);
        }

        // Cambia el tamaño del control.
        private void pictureBox1_Resize(object sender, EventArgs e)
        {
            int ancho = pictureBox1.ClientSize.Width;
            int alto = pictureBox1.ClientSize.Height;

            m_lavadora = new GraphicsPath();

            m_lavadora.AddEllipse(20, 20, ancho - 40, alto - 40);
            m_lavadora.CloseFigure();
            m_lavadora.AddLine(20, (alto / 2), ancho - 20, (alto / 2));
            m_lavadora.CloseFigure();
            m_lavadora.AddLine(ancho / 2, 20, ancho / 2, alto - 20);
            m_lavadora.CloseFigure();

            m_agua = new GraphicsPath();

            m_agua.AddArc(20, 20, ancho - 40, alto - 40, trackBar_Nivel_de_agua, 180 - 2 * trackBar_Nivel_de_agua);
            m_agua.CloseFigure();
        }

        // Conectar comunicación con el puerto serie.
        private void button_Conectar_Click(object sender, EventArgs e)
        {
            try
            {
                serialPort1.PortName = comboBox_Puerto.Text.ToString(); // Puerto seleccionado previamente.
                serialPort1.BaudRate = Convert.ToInt32(comboBox_Baudios.Text); // Baudios.
                serialPort1.Open(); // Abrir puerto.
                comboBox_Puerto.Enabled = false;
                comboBox_Baudios.Enabled = false;
                button_Conectar.Enabled = false;
                button_Desconectar.Enabled = true;
            }
            catch
            {
                MessageBox.Show("El puerto no existe.", "Aviso:",
                MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        // Desconectar comunicación con el puerto serie.
        private void button_Desconectar_Click(object sender, EventArgs e)
        {
            try
            {
                serialPort1.Close(); // Cerrar puerto.
                comboBox_Puerto.Enabled = true;
                comboBox_Baudios.Enabled = true;
                button_Conectar.Enabled = true;
                button_Desconectar.Enabled = false;
            }

            catch (Exception error)
            {
                MessageBox.Show(error.Message, "Aviso:",
                MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        // Al cerrar el formulario, antes cierra el puerto si está abierto.
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                serialPort1.Close(); // Cerrar puerto.
            }

            catch (Exception error)
            {
                MessageBox.Show(error.Message, "Aviso:",
                MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        // Recibe datos por el puerto serie.
        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            // Caracter/es disponible/s desde la última vez.
            string recibidos = serialPort1.ReadExisting();

            // analizamos cada caracter recibido
            foreach (char item in recibidos)
            {
                switch (item)
                {
                    // Ignoramos el \u000D
                    case '\r':
                        break;

                    // Aquí detectamos el final de la trama \u000A
                    case '\n':
                        // y la enviamos al control.
                        Invoke(NuevaTrama, sb.ToString());

                        // Luego limpiamos el búfer.
                        sb.Clear();
                        break;

                    // Cualquier otro caracter recibido, lo agregamos al búfer.
                    default:
                        sb.Append(item);
                        break;
                }
            }
        }

        private void Actualizar(string trama)
        {
            // Delimitador. Ignoramos las comas.
            string[] datosArray = trama.Split(',');

            // Compara si dos datos del array es igual a la cantidad total que en este
            // caso son 2. Si es igual a 2, entonces ejecuta todo el código dentro del if.
            if (datosArray.Length == 2)
            {
                // Mostrar datos.
                label_Entrada_analogica_A1.Text = "Entrada Analógica A1: " + datosArray[0];
                label_Entrada_analogica_A2.Text = "Entrada Analógica A2: " + datosArray[1];
            }
        }

        private void trackBar_Nivel_de_agua_ValueChanged(object sender, EventArgs e)
        {
            m_agua = new GraphicsPath();

            m_agua.AddArc(20, 20, pictureBox1.ClientSize.Width - 40, pictureBox1.ClientSize.Height - 40, -trackBar_Nivel_de_agua, 180 - 2 * -trackBar_Nivel_de_agua);
            m_agua.CloseFigure();
            pictureBox1.Refresh();
        }
    }
}


¿Alguna idea de este proyectado tipo reto?

Un cordial saludos camaradas.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/