Arduino与3个RS485设备通信



这个项目是我为一个学生的期末论文做的。它很简单,但我就是想不出怎么做。我在一个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;
}

最新更新