For a school project I am creating a pong game connected to the arduino, where if you hold a button pressed the racket moves in one direction and if you don't it moves in the other. The game works fine if I don't use arduino data as an input. I tried using different functions but it doesnt work.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
namespace pong
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
namespace pong
{
public partial class Form1 : Form
{
SerialPort port1 = new SerialPort();
public int points = 0;
public int speed_left = 0;
public int speed_top = 0;
public Form1()
{
InitializeComponent();
timer1.Enabled = true;
Cursor.Hide(); //skrije kurzor
this.TopMost = true;
this.Bounds = Screen.PrimaryScreen.Bounds;
this.FormBorderStyle = FormBorderStyle.None;
racket.Top = panel1.Bottom - (panel1.Bottom / 10);
SerialPort port1 = new SerialPort("COM3");
port1.BaudRate = 9600;
port1.Parity = Parity.None;
port1.StopBits = StopBits.One;
port1.DataBits = 8;
port1.Handshake = Handshake.None;
port1.RtsEnable = true;
port1.Open();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
if(!port1.IsOpen)
{
port1.Open();
port1.ReadTimeout = 1000;
}
if (port1.IsOpen)
{
if (port1.ReadExisting()=="")
{
racket.Left = racket.Left - 0;
}
else
{
racket.Left = racket.Left + 10;
}
}
ball.Left += speed_left;
ball.Top += speed_top;
if(ball.Bottom >=racket.Top && ball.Bottom <= racket.Bottom && ball.Left >= racket.Left && ball.Right <= racket.Right)
{
speed_left += 2;
speed_top += 2;
speed_top = -speed_top;
points += 1;
label2.Text = points.ToString();
}
if(ball.Left<=panel1.Left)
{
speed_left = -speed_left;
}
if (ball.Right >= panel1.Right)
{
speed_left = -speed_left;
}
if(ball.Top <= panel1.Top)
{
speed_top = -speed_top;
}
if(ball.Bottom>=panel1.Bottom)
{
timer1.Enabled=false;
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode==Keys.Escape)
{
this.Close();
}
}
private void label1_Click(object sender, EventArgs e)
{
}
}
}
arduino:
void setup() {
// put your setup code here, to run once:
pinMode(8,INPUT);
digitalWrite(8,LOW);
}
void loop() {
Serial.begin(9600);
while(1){
if(digitalRead(8)==HIGH)
{
Serial.write('1');
}
}
}
I would suggest putting a breakpoint in timer1_Tick, I suspect it is not going to be called at all because you haven't called
timer1.Start();
to start the timer.
Related
I am developing a graphical interface that reads variables from different sensors that arrive through the serial port, so far I have managed to read all the variables with a single form but now I want to have two forms.
The first form asks the user to choose the COM and confirms whether the connection was successful or not. Once the connection is successful, the second form is opened where the variables from the sensors will be shown in "labels", the readings sent from Arduino are read by the serial port and stored in an array:
data[0], data[1], data[2] etc...
This is the first form where Serialport1 is found and the data arrives through the serialPort1_DataReceived event:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Media;
namespace AUTOCLAVES_GUI
{
public partial class GUI_AUTOCLAVES_GENERADOR_DE_VAPOR : Form
{
/*VARIABLES GLOBALES*/
string puerto_seleccionado;
public GUI_AUTOCLAVES_GENERADOR_DE_VAPOR()
{
InitializeComponent();
string[] puertos = SerialPort.GetPortNames();
foreach (string mostrar in puertos)
{
comboBox1.Items.Add(mostrar);
}
}
private void Salir_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void Minimizar_Click(object sender, EventArgs e)
{
WindowState = FormWindowState.Minimized;
}
private void Maximizar_Click(object sender, EventArgs e)
{
WindowState = FormWindowState.Maximized;
Maximizar.Visible = false;
Restaurar.Visible = true;
}
private void Restaurar_Click(object sender, EventArgs e)
{
WindowState = FormWindowState.Normal;
Restaurar.Visible = false;
Maximizar.Visible = true;
}
private void MenuSideBar_Click(object sender, EventArgs e)
{
if (Sidebar.Width == 270)
{
Sidebar.Visible = false;
Sidebar.Width = 68;
SidebarWrapper.Width = 90;
LineaSidebar.Width = 68;
AnimacionSidebar.Show(Sidebar);
}
else
{
Sidebar.Visible = false;
Sidebar.Width = 270;
SidebarWrapper.Width = 300;
LineaSidebar.Width = 268;
AnimacionSidebarBack.Show(Sidebar);
}
}
private void bunifuFlatButton8_Click(object sender, EventArgs e)
{
try
{
serialPort1.Close();
serialPort1.Dispose();
serialPort1.Open();
CheckForIllegalCrossThreadCalls = false;
label2.Text = "CONEXIÓN EXITOSA";
label2.ForeColor = Color.Green;
label2.Font = new Font(label2.Font, FontStyle.Bold);
openChildForm(new MUESTREO_EN_TIEMPO_REAL());
}
catch
{
label2.Text = "CONEXIÓN FALLIDA";
label2.ForeColor = Color.Red;
label2.Font = new Font(label2.Font, FontStyle.Bold);
MessageBox.Show("REVISE CONEXIÓN DE ARDUINO", "ADVERTENCIA", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
puerto_seleccionado = comboBox1.Text;
serialPort1.PortName = puerto_seleccionado;
}
private void bunifuFlatButton7_Click(object sender, EventArgs e)
{
comboBox1.Items.Clear();
label2.Text = "SIN CONEXIÓN";
label2.ForeColor = Color.White;
string[] puertos = SerialPort.GetPortNames();
foreach (string mostrar in puertos)
{
comboBox1.Items.Add(mostrar);
}
}
private Form activeForm = null;
private void openChildForm(Form childForm)
{
if (activeForm != null)
activeForm.Close();
activeForm = childForm;
childForm.TopLevel = false;
childForm.FormBorderStyle = FormBorderStyle.None;
childForm.Dock = DockStyle.Fill;
panel1.Controls.Add(childForm);
panel1.Tag = childForm;
childForm.BringToFront();
childForm.Show();
}
private void bunifuFlatButton2_Click(object sender, EventArgs e)
{
openChildForm(new MUESTREO_EN_TIEMPO_REAL());
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string[] data = serialPort1.ReadLine().Split(',');
if (data.Length > 10)
{
}
else
{
MessageBox.Show("Intente nuevamente", "ADVERTENCIA", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
}
}
}
}
Here is my second form:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AUTOCLAVES_GUI
{
public partial class MUESTREO_EN_TIEMPO_REAL : Form
{
public MUESTREO_EN_TIEMPO_REAL()
{
InitializeComponent();
}
private void MUESTREO_EN_TIEMPO_REAL_Load(object sender, EventArgs e)
{
}
private void Salir_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
I hope someone can help me overcome this problem.
I'm trying to set a maximum value of a metro theme trackbar using an integer from WindowsMediaPlayer's current media however it keeps throwing the following error:
Specified argument was out of the range of valid values.
Parameter name: Maximal value is lower than minimal one
This means that the maximum value is not being set at all, I'm not sure why.
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MetroFramework;
using MetroFramework.Forms;
using VideoLibrary;
using System.IO;
using System.Threading;
using System.Diagnostics;
using WMPLib;
using UITimer = System.Windows.Forms.Timer;
namespace Composer
{
public partial class Form1 : MetroForm
{
private string _pDirectory;
private string[] _songs;
private int _sIndex;
private WindowsMediaPlayer wmp;
private UITimer _timer;
public Form1()
{
InitializeComponent();
}
private void metroTrackBar1_Scroll(object sender, ScrollEventArgs e)
{
wmp.settings.volume = metroTrackBar1.Value;
}
private void metroTile3_Click(object sender, EventArgs e)
{
playAudio(Path.Combine(_pDirectory, _songs[_sIndex]));
}
private void playAudio(string path)
{
wmp.URL = path;
wmp.controls.play();
_timer.Start();
displayHeader(path);
metroTrackBar2.Maximum = (int)wmp.currentMedia.duration;
}
private void t_Tick(object sender, EventArgs e)
{
metroTrackBar2.Value = (int)wmp.controls.currentPosition;
}
private void displayHeader(string song)
{
MethodInvoker invoke = new MethodInvoker(delegate
{
metroTile1.Text = Path.GetFileNameWithoutExtension(_songs[_sIndex]);
});
this.Invoke(invoke);
}
private void Form1_Load(object sender, EventArgs e)
{
string bin;
_sIndex = 0;
_pDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), #"Composer\");
bin = Path.Combine(_pDirectory, "bin");
_timer = new UITimer();
_timer.Interval = 1000;
_timer.Tick += new EventHandler(t_Tick);
if (!Directory.Exists(_pDirectory))
{
Directory.CreateDirectory(_pDirectory);
if(!Directory.Exists(bin))
{
Directory.CreateDirectory(bin);
}
} else
{
_songs = Directory.GetFiles(bin);
}
wmp = new WindowsMediaPlayer();
//MessageBox.Show(_pDirectory);
}
private void metroTile4_Click(object sender, EventArgs e)
{
if(_sIndex == (_songs.Length - 1))
{
_sIndex = 0;
} else
{
_sIndex++;
}
playAudio(Path.Combine(_pDirectory, _songs[_sIndex]));
}
}
}
first of all i want you to know that i know that there a lot of results for this question, but i have searched far and wide still haven't come up with a solution for my problem.
i have tried to do the following:
1.constructor
2.objects
3.properties
4.delegates
but none of my implementation of them really did worked as wanted (in this "solution" i have used properties
when i press "back" on the "pop up" screen i dont in the main screen the value i choose from in the "pop up" screen
basically, it's something like, i have main screen and a "pop up"
the main screen
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BakaritCV
{
public partial class FrmProdChoose : MetroFramework.Forms.MetroForm
{
CVFeedUtilities utilities = new CVFeedUtilities();
Mixtures mixture;
public string selectedDefault = " 102";
string t;
public FrmProdChoose(string t)
{
InitializeComponent();
this.t = t;
}
public FrmProdChoose()
{
InitializeComponent();
}
private void btnHome_Click(object sender, EventArgs e)
{
FrmMain frmload = new FrmMain();
utilities.moveBetweenScreens(this, frmload);
}
private void mixtureBtn_Click(object sender, EventArgs e)
{
utilities.loadPopUp(this, mixture);
}
private void FrmProdChoose_Load(object sender, EventArgs e)
{
mixture = new Mixtures(this);
mixtureBtn.Text = selectedDefault;
}
public string Selected
{
get { return selectedDefault; }
set { selectedDefault = value; }
}
}
}
the "pop up"
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BakaritCV
{
public partial class Mixtures : MetroFramework.Forms.MetroForm
{
string[] mixture = new string[] { "102", "103", "104", "105" };
MetroFramework.Controls.MetroTile[] tiles;
FrmProdChoose form;
string selectedDefault;
CVFeedUtilities utilities = new CVFeedUtilities();
public Mixtures(FrmProdChoose form)
{
InitializeComponent();
this.form = form;
}
private void btnHome_Click(object sender, EventArgs e)
{
form.Selected = selectedDefault;
utilities.closePopUp(this, form);
}
private void Mixtures_Load(object sender, EventArgs e)
{
tiles = new MetroFramework.Controls.MetroTile[] { tileOne, tileTwo, tileThree, tileFour};
for (int i = 0; i < mixture.Length; i++)
tiles[i].Text = mixture[i];
}
private void tileOne_Click(object sender, EventArgs e)
{
tileOne.BackColor = Color.ForestGreen;
removeBackColor(1);
}
private void tileTwo_Click(object sender, EventArgs e)
{
tileTwo.BackColor = Color.ForestGreen;
removeBackColor(2);
}
private void tileThree_Click(object sender, EventArgs e)
{
tileThree.BackColor = Color.ForestGreen;
removeBackColor(3);
}
private void tileFour_Click(object sender, EventArgs e)
{
tileFour.BackColor = Color.ForestGreen;
removeBackColor(4);
}
private void tileFive_Click(object sender, EventArgs e)
{
tileFive.BackColor = Color.ForestGreen;
removeBackColor(5);
}
public void removeBackColor(int index)
{
for (int i = 0; i < tiles.Length; i++)
{
if (i == index - 1)
{
selectedDefault = tiles[i].Text;
continue;
}
else tiles[i].BackColor = Color.DeepSkyBlue;
}
}
}
}
and the functions loadPopUp and closePopUp
public void loadPopUp(Form from, Form to)
{
to.Tag = from;
to.Show(from);
}
public void closePopUp(Form from, Form to)
{
to.Tag = from;
if (!to.Visible)
to.Show(from);
from.Hide();
}
I created a default form in Visual Studio 2010 and on the form design I have not changed anything. I only added following code in Form1.cs:
using System;
using System.Windows.Forms;
namespace WinFormTest1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.TopMost = true;
this.ShowInTaskbar = true;
this.Load += new EventHandler(Form1_Load);
this.Shown += new EventHandler(Form1_Shown);
}
void Form1_Load(object sender, EventArgs e)
{
this.Opacity = 0;
}
void Form1_Shown(object sender, EventArgs e)
{
this.Opacity = 1;
}
}
}
Starting this program the form does not appear on the taskbar. It only appears on the task bar when made active any other window, and then activating this form.
What is the reason of such behavior?
Edited:
Why do I need to set the opacity of it in handler Form1_Load?
I created class FormAppearingEffect whose code below:
using System;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;
namespace AG.FormAdditions
{
public class FormAppearingEffect
{
private Form form;
double originalOpacity;
public FormAppearingEffect(Form form)
{
this.form = form;
form.Load += form_Load;
form.Shown += form_Shown;
}
void form_Load(object sender, EventArgs e)
{
originalOpacity = form.Opacity;
form.Opacity = 0;
}
private void form_Shown(object sender, EventArgs e)
{
try
{
double currentOpacity = 0;
form.Opacity = currentOpacity;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 1; currentOpacity < originalOpacity; i++)
{
currentOpacity = 0.1 * i;
form.Opacity = currentOpacity;
Application.DoEvents();
//if processor loaded and does not have enough time for drawing form, then skip certain count of steps
int waitMiliseconds = (int)(50 * i - stopwatch.ElapsedMilliseconds);
if (waitMiliseconds >= 0)
Thread.Sleep(waitMiliseconds);
else
i -= waitMiliseconds / 50 - 1;
}
stopwatch.Stop();
form.Opacity = originalOpacity;
}
catch (ObjectDisposedException) { }
}
}
}
In any form of program I use this class like this:
using System;
using System.Windows.Forms;
using AG.FormAdditions;
namespace WinFormTest1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
FormAppearingEffect frmEffects = new FormAppearingEffect(this);
}
}
}
Thus my form appears on the screen "gradually".
This is where I found a bug, which we are in this topic.
And that's it for this reason I need to set the opacity in the event handlers.
I'm trying to make a app that read the outgoing signals from Arduino, but I can't make it work in C# Windows Forms, only in the console. Is my C# Windows Forms code wrong? I don't get any errors when I debug, but it doesn't mean that I haven't forgot something.
Here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
namespace CommunicateWithArduino
{
public partial class Form1 : Form
{
public static System.IO.Ports.SerialPort port;
delegate void SetTextCallback(string text);
private BackgroundWorker hardWorker;
private Thread readThread = null;
public Form1()
{
InitializeComponent();
hardWorker = new BackgroundWorker();
sendBtn.Enabled = false;
}
private void btnConnect_Click(object sender, EventArgs e)
{
System.ComponentModel.IContainer components =
new System.ComponentModel.Container();
port = new System.IO.Ports.SerialPort(components);
port.PortName = comPort.SelectedItem.ToString();
port.BaudRate = Int32.Parse(baudRate.SelectedItem.ToString());
port.DtrEnable = true;
port.ReadTimeout = 5000;
port.WriteTimeout = 500;
port.Open();
readThread = new Thread(new ThreadStart(this.Read));
readThread.Start();
this.hardWorker.RunWorkerAsync();
btnConnect.Text = "<Connected>";
btnConnect.Enabled = false;
comPort.Enabled = false;
sendBtn.Enabled = true;
}
private void Form1_Load(object sender, EventArgs e)
{
foreach (string s in SerialPort.GetPortNames())
{
comPort.Items.Add(s);
}
if (comPort.Items.Count > 0)
comPort.SelectedIndex = comPort.Items.Count-1;
else
comPort.SelectedIndex = 0;
baudRate.Items.Add("2400");
baudRate.Items.Add("4800");
baudRate.Items.Add("9600");
baudRate.Items.Add("14400");
baudRate.Items.Add("19200");
baudRate.Items.Add("28800");
baudRate.Items.Add("38400");
baudRate.Items.Add("57600");
baudRate.Items.Add("115200");
baudRate.SelectedIndex = 2;
}
private void sendBtn_Click(object sender, EventArgs e)
{
if (port.IsOpen)
{
port.Write(sendText.Text);
}
}
private void SetText(string text)
{
if (this.receiveText.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.receiveText.Text += "Text: ";
this.receiveText.Text += text;
this.receiveText.Text += Environment.NewLine;
}
}
public void Read()
{
while (port.IsOpen)
{
try
{
if (port.BytesToRead > 0)
{
string message = port.ReadLine();
this.SetText(message);
}
}
catch (TimeoutException) { }
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
try
{
if(!(readThread == null))
readThread.Abort();
}
catch (NullReferenceException)
{
}
try
{
port.Close();
}
catch (NullReferenceException)
{
}
}
}
}
By default, the ReadLine method will block until a line is received. Is your Arduino program sending a line? Did you close the Arduino serial monitor program while running your program?
I would change to port.ReadChar until you verify that you are receiving characters.