这个项目是我为一个学生的期末论文做的。它很简单,但我就是想不出怎么做。我在一个arduino上有RPM计数器和RS232通信。转速计数器工作良好,但通信不。我有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, ' ');
}
它返回正确的数据,但是在字符串
的末尾有 或n。{MESSAGE:Stendas|DATA|
0,01ST,GS, 0.03,kg
0,02ST,GS, 0.00,kg
0,03ST,GS, 0.00,kg
所以我需要删除最后一个字符 或n或其他字符
如果你真的想每次读取固定大小的19字节,你可以这样做(原谅我生锈的arduino技能,你可能不得不纠正我)
void READ01() { momentas1 = READ("01READ"); }
void READ02() { momentas2 = READ("02READ"); }
void READ03() { momentas3 = READ("03READ"); }
String READ(String toSend) {
mySerial.println(toSend);
String buffer = "";
int i = 0;
while (i < 19)
{
while (!Serial.available()) { /* Busy wait for next byte */ }
buffer += Serial.read();
}
buffer.Trim();
return buffer;
}
应该用来自该设备的19字节的数据填充相应的read_buffer
经过艰苦的努力,我得到了同事的帮助。我们都找到了解决办法:添加了带注释的正确代码。感谢Hans Pasant和Joachim Isaksson的建议!!正确的答案是一直读到'n'(换行)字符出现为止。
void READ02(){
while (mySerial.available()){ // Flush read buffer
mySerial.read();
}
mySerial.println("02READ"); // Send command for second device
momentas2="";
delay(20); // Wait some time
while (mySerial.available()) { //While there is data count it to string
char c = mySerial.read();
if (c == 'n'){ //If read char is new line then break.
break;
}
momentas2 += c;
}
}
和重新处理字符串以获得我需要的数据,在第二和第三个','之间存储数据。
String between2ndAnd3rd(String myString) {
int pirmas = myString.indexOf(',');
int antras = myString.indexOf(',', pirmas+1);
int trecias = myString.indexOf(',', antras+1);
int ketvirtas = myString.indexOf(',', trecias+1);
String newStr = myString.substring(antras+1, trecias);
return newStr;
}