使用来自串行端口的字符串数据来操作振镜扫描仪在更高的速度下会出错
Using stringdata from serial port to manipulate galvo scanners goes wrong at higher speeds
我正在使用振镜扫描仪来操纵激光。我从串行端口获取数据。此外,我正在将数据发送回串行监视器,在那里我没有任何问题。因此,问题应该是将数据从arduino传输到显示器和振镜驱动程序。如果我在 python 端使用 timesleep=1 秒,它可以工作。但它需要更快。
我已经尝试更改一些延迟并调整波特率。
我使用的Arduino代码:
///// Declaration for laser
#include "Laser.h"
// Create laser instance (with laser pointer connected to digital pin 5)
Laser laser(5);
///// Declaration for the OLED /////
#include "U8glib.h" // LCD Lib
//define ADDRESS 0x3C// address of display
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);
///// Declatation of variables /////
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
// variables to hold the parsed data
char messageFromPC[numChars] = {0};
int integerFromPC = "";
int integerFromPC2 = 0;
int integerFromPC3 = 0;
//float floatFromPC = 0.0;
boolean newData = false;
//===============================================
///////////////////////////////
///////////// Setup ///////////
///////////////////////////////
void setup()
{
Serial.begin(9600); //9600 Standard
laser.init();
//laser.resetClipArea();
laser.setScale(1);
//laser.setOffset(0,0);
// assign default color value
if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
u8g.setColorIndex(255); // white
}
else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
u8g.setColorIndex(3); // max intensity
}
else if ( u8g.getMode() == U8G_MODE_BW ) {
u8g.setColorIndex(1); // pixel on
}
else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
u8g.setHiColorByRGB(255,255,255);
}
pinMode(8, OUTPUT);
}
//===============================================
///////////////////////////////
///////////// Loop ////////////
///////////////////////////////
void loop() {
///// OLED: wait for serial /////
u8g.firstPage();
do {
draw();
}
while( u8g.nextPage() );
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with
parseData();
showParsedData();
newData = false;
}
SerToLaser();
// delay(10);
}
//========================================================
///////////////////////////////
////////// Functions //////////
///////////////////////////////
///// Info before receiving serial information /////
void draw(void) {
u8g.setFont(u8g_font_unifont);
//u8g.setFont(u8g_font_osb21);
u8g.drawStr( 5, 10, "ser_data: NO");
u8g.drawStr( 5, 25, "Laser: OFF");
u8g.drawStr( 5, 45, "x: --");
u8g.drawStr( 65, 45, "y: --");
}
///// Info when receiving serial information & print received values /////
void draw2(void) {
// graphic commands to redraw the complete screen should be placed here
u8g.setFont(u8g_font_unifont);
//u8g.setFont(u8g_font_osb21);
u8g.drawStr( 5, 10, "ser_data: YES");
u8g.drawStr( 5, 25, "Laser:");
u8g.setPrintPos(65, 25); // set position 25,35
u8g.print(messageFromPC); // display laser status
u8g.drawStr( 5, 45, "x:");
u8g.setPrintPos(20, 45); // set position 25,35
u8g.print(integerFromPC2); // display x-coordinate
u8g.drawStr( 65, 45, "y: ");
u8g.setPrintPos(80, 45); // set position 25,35
u8g.print(integerFromPC3); // display y-coordinate
}
void SerToLaser(){
switch (integerFromPC) {
case 1:
{
// int serDataX = Serial.parseInt();
// int serDataY = Serial.parseInt();
laser.sendtoRaw(integerFromPC2, integerFromPC3);
laser.on();
// picture loop
u8g.firstPage();
do {
draw2();
} while( u8g.nextPage() );
integerFromPC = "";
//delay(200); ////////////////
break;
}
case 0:
{
laser.off();
// int serDataX = Serial.parseInt();
// int serDataY = Serial.parseInt();
laser.sendtoRaw(integerFromPC2, integerFromPC3);
// picture loop
u8g.firstPage();
do {
draw2();
} while( u8g.nextPage() );
integerFromPC = "";
//delay(200); ////////////////
break;
}
default:
break;
}
}
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = ' '; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
//============
void parseData() { // split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars,","); // get the first part - the string
strcpy(messageFromPC, strtokIndx); // copy it to messageFromPC
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
integerFromPC = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
integerFromPC2 = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
integerFromPC3 = atoi(strtokIndx); // convert this part to an integer
//strtokIndx = strtok(NULL, ",");
//floatFromPC = atof(strtokIndx); // convert this part to a float
}
//============
void showParsedData() {
Serial.print("Laserstatus: ");
Serial.println(messageFromPC);
Serial.print("Statusnumber: ");
Serial.println(integerFromPC);
Serial.print("X: ");
Serial.println(integerFromPC2);
Serial.print("Y: ");
Serial.println(integerFromPC3);
SerToLaser();
}
//============
我使用的 Python 代码:
import serial
import time
import random
ard = serial.Serial('com6',9600,timeout=5)
time.sleep(1.8) # wait for Arduino min 1.8
i = 0
while (i <4096):
# Serial write section
#int r = randint(0,100)
setX_Coor = i
setY_Coor = 2000
setStatus = 1#random.randint(0,1)
#setX_Coor = random.randint(1000,4095) #63
#setY_Coor = random.randint(1000,4095)#37
ard.flush()
setVal1 = str(setStatus)
setVal2 = str(setX_Coor)
setVal3 = str(setY_Coor)
print ("Python value sent: ")
print (setVal1.encode())
print (setVal2.encode())
print (setVal3.encode())
ard.write(('<').encode())
ard.write(('ON,').encode())
ard.write((',').encode())
ard.write(setVal1.encode())
ard.write((',').encode())
ard.write(setVal2.encode())
ard.write((',').encode())
ard.write(setVal3.encode())
ard.write(('>').encode())
time.sleep(1) # 0.08 is fastest possible value
# Serial read section
msg = ard.read(ard.inWaiting()) # read all characters in buffer
print ("Message from arduino: ")
print (msg)
i = i + 10
else:
print ("Exiting")
#exit()
扫描仪应扫描 y=2000 的线,并将 x 的值从 0 更改为 4095。它完成工作 3 秒,然后 y 值仅比 20 或 1 或一些随机数字 200 ......
乍一看,您似乎正在做很多多余的重绘(这可能很昂贵,我从未使用过u8glib(。 你在主循环的顶部重绘一次,然后由于你的 SerToLaser(( 两次(一次在主循环的底部,一次在 showParsedData(( 中(。 另外(虽然 1 秒一点也不快(,串行显示在 arduino 上非常昂贵,所以你应该节省打印到终端的数量。
相关文章:
- 访问者访问变体并返回不同类型时出错
- 在Linux for Windows上编译C++代码时出错
- 读取文件的最后一行并输入到链接列表时出错
- 重载操作程序时出错>>用于类中的字符串 memebr
- 调用专用模板时出错"no matching function for call to [...]"
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- LINK 尝试使用 OpenSSL evp aes 256 c++ 时出错
- 在Google Kick start中提交时出错
- 在c++中访问int到类对象的映射时出错
- 为什么在读取文件大小时文件IO速度会发生变化
- 分段错误当我试图运行程序时出错
- 使用dynamic_cast和构造函数时出错
- CHECK(调用)函数在Google Colab中出错
- 用pybind11包装C++抽象类时出错
- 为x86而非x64编译时出错
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- 文件系统:复制功能的速度秘诀是什么
- 从R调用C++函数并对其进行集成时出错
- 这个函数哪里出错了
- 使用来自串行端口的字符串数据来操作振镜扫描仪在更高的速度下会出错