【发布时间】:2014-05-19 15:17:31
【问题描述】:
我正在为一个学生的期末论文做这个项目。它很容易,但我就是想不出怎么做。我在一个 arduino 上有 RPM 计数器和 RS232 通信。 RPM 计数器工作正常,但通信不正常。 我有 3 个 RS485 设备 > RS485/RS232 转换器 > RS232/TTL > Arduino。 接收前。第二个设备信息我必须发送“02READ”。下面的示例,使用超级终端完成。
02READ
02ST,GS, 0.00,kg
002READ
02ST,GS, 0.00,kg
002READ
02ST,GS, 0.00,kg
002READ
02ST,GS, 0.00,kg
0
似乎设备正在发送终止0,所有消息都是02ST,GS, 0.00,kg。它的 19 个字节,对吧?要求 3 个设备然后打印它们以将它们记录在 pc 上的最佳解决方案是什么?这个我试过了,不正确。
void READ03(){
mySerial.println("03READ");
while (mySerial.available()) {
delay(10);
if (mySerial.available() >0) {
char c = mySerial.read();
readString += c;}
}
if (readString.length() == 19) {
momentas3 = readString;
readString="";
}
}
我必须去循环并收集传入的数据。但我不知道该怎么做:(太伤心了……
所有代码:
#include <SoftwareSerial.h>
#include <MegunoLink.h>
/*
Baltas +
Raudonas -
Pinout:
============= TCRT1 =============
Juodas - GND
Geltons - POSSITIVE
Pilkas - SIGNAL
============= TCRT2 =============
Rudas - GND
Oranzinis - POSSITIVE
Zydras - SIGNAL
============= TCRT3 =============
Zalias - GND
raudonas - POSSITIVE
Baltas - SIGNAL
*/
//Software serial for 485 communication : Tx = pin 9, Rx = pin 8.
SoftwareSerial mySerial(9,8);
TimePlot MyPlot;
//CONSTANTS:
//Pin number for Vishay Telefunken Opto-reflecting TCRT1000 sensors:
Message MyCSVMessage("Stendas");
#define TCRT1 12
#define TCRT2 11
#define TCRT3 10
String readString;
String momentas1;
String momentas2;
String momentas3;
//Number of pulse changes per revolutuion:
long PulsesPerRevolution1 = 78;
long PulsesPerRevolution2 = 192;
long PulsesPerRevolution3 = 82;
long minute = 60;
//VARIABLES:
//Number of pulses counted:
long PulseCount1=0;
long PulseCount2=0;
long PulseCount3=0;
//Calculated rotations per minute:
long Rpm1 =0;
long Rpm2 =0;
long Rpm3 =0;
//Time saved to compare
unsigned long TimeOld =0;
//Achieved signals saved:
boolean Status1 =0;
boolean Status2 =0;
boolean Status3 =0;
//Signals saved to compare:
boolean StatusOld1 =0;
boolean StatusOld2 =0;
boolean StatusOld3 =0;
void setup() {
//Begin serial communication with BAUD rate 9600bps:
Serial.begin(9600);
mySerial.begin(57600);
//Set input pins for TCRT1000:
pinMode(TCRT1, INPUT);
pinMode(TCRT2, INPUT);
pinMode(TCRT3, INPUT);
MyPlot.SetTitle("Greicio matavimas");
MyPlot.SetXlabel("Laikas");
MyPlot.SetYlabel("Greitis");
MyPlot.SetSeriesProperties("Rpm", Plot::Magenta, Plot::Solid, 2, Plot::Square);
}
void loop() {
//
//Read and save TCRT1000 status:
Status1=digitalRead(TCRT1);
Status2=digitalRead(TCRT2);
Status3=digitalRead(TCRT3);
//Compare current status with the previous one
//If changed, then increment the counting:
if (StatusOld1!=Status1){
StatusOld1=Status1;
PulseCount1++;
}
if (StatusOld2!=Status2){
StatusOld2=Status2;
PulseCount2++;
}
if (StatusOld3!=Status3){
StatusOld3=Status3;
PulseCount3++;
}
//Compare time if it exceeds 1s:
if (millis()-TimeOld>=1000){
//Get data from RS485:
READ01();
READ02();
READ03();
//Calculate RPM:
Rpm1=PulseCount1*minute/PulsesPerRevolution1;
Rpm2=PulseCount2*minute/PulsesPerRevolution2;
Rpm3=PulseCount3*minute/PulsesPerRevolution3;
//Print RPM
MyCSVMessage.Begin();
Serial.println(String(Rpm1) + "," + String(momentas1));
Serial.println(String(Rpm2) + "," + String(momentas2));
Serial.println(String(Rpm3) + "," + String(momentas3));
MyCSVMessage.End();
MyPlot.SendData("Rpm1", Rpm1);
MyPlot.SendData("Rpm2", Rpm2);
MyPlot.SendData("Rpm3", Rpm3);
//reset the counting and time
TimeOld=millis();
PulseCount1=0;
PulseCount2=0;
PulseCount3=0;
}
}
//Get data from RS485:
void READ01(){
readString="";
mySerial.println("01READ");
while (mySerial.available()) {
delay(10);
if (mySerial.available() >0) {
char c = mySerial.read();
readString += c;}
}
if (readString.length() == 19) {
momentas1 = readString;
readString="";
}
}
void READ02(){
readString="";
mySerial.println("02READ");
while (mySerial.available()) {
delay(10);
if (mySerial.available() >0) {
char c = mySerial.read();
readString += c;}
}
if (readString.length() == 19) {
momentas2 = readString;
readString="";
}
}
void READ03(){
readString="";
mySerial.println("03READ");
while (mySerial.available()) {
delay(10);
if (mySerial.available() >0) {
char c = mySerial.read();
readString += c;}
}
if (readString.length() == 19) {
momentas3 = readString;
readString="";
}
}
已编辑作废:
void READ03(){
while (mySerial.available()){
mySerial.read();
}
mySerial.println("03READ");
momentas3="";
delay(20);
while (mySerial.available()) {
char c = mySerial.read();
momentas3 += c;
}
// momentas3 = readString;
//momentas3.setCharAt(momentas3.length() - 1, '\0');
}
返回正确的数据,但字符串末尾有\0或\n
{MESSAGE:Stendas|DATA|
0,01ST,GS, 0.03,kg
0,02ST,GS, 0.00,kg
0,03ST,GS, 0.00,kg
所以我需要删除最后一个字符 \0 或 \n 或其他任何内容
【问题讨论】:
-
它不发送 19 个字符,它发送 20 个字符。额外的一个是换行符,'\n',这就是你知道你得到了整个响应而不必计算的方式。由于您没有阅读它,因此您阅读的下一个字符串将以上一个响应中的换行符开头。
-
谢谢汉斯,阅读直到\n帮助
-
如果
read()正在获取 ASCII 字符和\n和/或 NUL 终止,那么您应该编写代码来处理输入字符串,而不是按字节数指定或限制输入。您真的不想“删除最后一个字符 \0 或 \n 或其他任何字符”,而是使用适当的字符串终止符(即 NUL 字符)存储输入。您正在接收规范输入,但试图将其视为原始数据或二进制数据。
标签: serial-port arduino