提问人:Ozzie 提问时间:11/16/2023 更新时间:11/17/2023 访问量:42
如何通过接受当前位置作为第一个坐标来重新启动电机
How to restart motors by accepting current position as first coordinate
问:
我有一个 C# 代码,可以生成一些 x 和 y 坐标,我将这些坐标作为 g 代码发送到针对 2 轴 cnc 代码编程的 arduino。
我在列表框中列出了所有坐标,并在 750 毫秒后将每个坐标发送到 arduino。
我的问题是,当所有坐标都发送到arduino时,我想一次又一次地重新发送所有坐标,直到发送停止命令。但是,当坐标重新发送到 arduino 时,电机会按预期移动到第一个坐标的位置。 但是,我想要的是电机将当前坐标作为列表框中的第一个坐标,而不是移回第一个起点。
请帮我如何重新调整代码。
我正在将当前代码添加到下面。
private void btnSendData_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen && listBox1.Items.Count > 1)
{
currentIndex = 0; // Reset the index to start from the first item
timer1.Interval = 750; // in mili-second
timer1.Start();
}
else
{
MessageBox.Show("Port Closed or Not Enough Data");
}
}
private void SendDataToArduino()
{
if (currentIndex < listBox1.Items.Count)
{
string command = listBox1.Items[currentIndex].ToString(); // Get the item as a string
command = command.Replace(": ", ""); // Remove the colon
command = command.Replace(",", ""); // Remove comma if needed
serialPort1.WriteLine(command);
textBox3.Text = command;
currentIndex++; // Move to the next item
}
else
{
// Tüm veriler gönderildi, işlemi yeniden başlat
currentIndex = 0;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
SendDataToArduino();
}
我尝试将每个 x 值添加到每个循环中的第一个坐标中。但这太荒谬了。
答:
根据我们在评论中讨论的内容,我创建了一个小型 Winforms 项目来模拟您要实现的目标。
首先,我添加了几个控件:
- listBox2:保存电机要重复的图案的位置
- btnCalculatePattern:单击时,根据您在 listBox1 中设置的坐标计算重复模式
- btnAvatar:这只是通过移动按钮在屏幕上显示电机的运动。
我还启用了控制台窗口,以便查看发送到电机的命令。
首先,在向电机发送命令之前,单击“计算模式”来计算模式。之后,单击“发送数据”,这将激活计时器(如原始代码中)并开始发送数据:
您可以在此 GitHub 存储库中找到整个解决方案,也可以在此处将其下载为 zip 文件。如果您在打开它时遇到任何问题,请告诉我。
我不知道您以什么格式将数据发送到电机,所以我只使用了格式为“X.Y”的字符串,用点“.”分隔,因此您可能需要使用您正在使用的字符串格式调整此部分。
这是具有新更改的 Form1 代码。我不得不将命令变量移出 SendDataToArduino,对此方法进行了一些更改,并添加了其他方法btnCalculatePattern_Click 和 UpdateCoordinates:
public partial class Form1 : Form
{
bool serialPortIsOpen = true;
int currentIndex = 0;
string command = "";
public Form1()
{
InitializeComponent();
//Move the visual avatar to the starting position
MoveAvatar(listBox1.Items[0].ToString());
}
private void MoveAvatar(string point)
{
var currentCoordinates = point.Split('.');
var current_x = Convert.ToInt32(currentCoordinates[0]);
var current_y = Convert.ToInt32(currentCoordinates[1]);
btnAvatar.Location = new System.Drawing.Point(current_x, current_y);
}
private void btnSendData_Click(object sender, EventArgs e)
{
if (serialPortIsOpen && listBox1.Items.Count > 1)
{
currentIndex = 0; // Reset the index to start from the first item
timer1.Interval = 750; // in mili-second
timer1.Start();
}
else
{
MessageBox.Show("Port Closed or Not Enough Data");
}
}
private void btnCalculatePattern_Click(object sender, EventArgs e)
{
// The first item of the pattern is always (0,0)
listBox2.Items.Add($"0.0");
for (int i = 0; i < listBox1.Items.Count - 1; i++)
{
var currentCoordinates = listBox1.Items[i].ToString().Split('.');
var current_x = Convert.ToInt32(currentCoordinates[0]);
var current_y = Convert.ToInt32(currentCoordinates[1]);
var nextCoordinates = listBox1.Items[i + 1].ToString().Split('.');
var next_x = Convert.ToInt32(nextCoordinates[0]);
var next_y = Convert.ToInt32(nextCoordinates[1]);
var x = next_x - current_x;
var y = next_y - current_y;
listBox2.Items.Add($"{x}.{y}");
}
btnCalculatePattern.Enabled = false;
btnSendData.Enabled = true;
}
private void UpdateCoordinates(string startingPoint)
{
// The startingPoint is the ending point of the last iteration
listBox1.Items[0] = startingPoint;
var startingPointSplit = startingPoint.Split(".");
var startingPoint_x = Convert.ToInt32(startingPointSplit[0]);
var startingPoint_y = Convert.ToInt32(startingPointSplit[1]);
// Calculate the rest of the coordinates for this iteration from
// the starting point and the pattern
var x = startingPoint_x;
var y = startingPoint_y;
for (int i = 0; i < listBox1.Items.Count; i++)
{
var pattern = listBox2.Items[i].ToString().Split('.');
var pattern_x = Convert.ToInt32(pattern[0]);
var pattern_y = Convert.ToInt32(pattern[1]);
x += pattern_x;
y += pattern_y;
listBox1.Items[i] = $"{x}.{y}";
}
}
private void SendDataToArduino()
{
// Send commands with the current state of Coordinates
if (currentIndex < listBox1.Items.Count)
{
command = listBox1.Items[currentIndex].ToString();
command = command.Replace(": ", ""); // Remove the colon
command = command.Replace(",", ""); // Remove comma if needed
//We move the visual avatar and print the coordinates to the console
// to simulate the motor receiving the commands
// serialPort1.WriteLine(command);
Console.WriteLine(command);
MoveAvatar(command);
textBox3.Text = command;
currentIndex++; // Move to the next item
}
else
{
// Tüm veriler gönderildi, işlemi yeniden başlat
currentIndex = 0;
// Update the Coordinates in the listBox with the Pattern information
// passing the last point of the current iteration
// as the starting point of the next iteration.
UpdateCoordinates(command);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
SendDataToArduino();
}
}
下一个:消除等高线交叉点
评论
currentIndex
currentIndex == 0