--
MAX485
最後的腳位對應為
1 2 3 |
RO => RXD = D5 DI => TXD = D6 TR = D2 |
--
SoftwareSerial
因為使用了 UART 轉 RS485 小板,因此只要設定好鮑率、傳送的資料及計算 CRC 即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <SoftwareSerial.h> SoftwareSerial mySerial(14, 12); // RX, TX #define DE 4 // D6使能發送器,高電平有效 void setup() { pinMode(not_RE, OUTPUT); pinMode(DE, OUTPUT); digitalWrite(not_RE, HIGH); // disable receiver digitalWrite(DE, HIGH); // enable transmitter Serial.begin(57600); mySerial.begin(9600); } void loop() { Serial.println("aaa"); mySerial.println("aaa"); delay(100); } |
--
CRC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
uint16_t CalcCRC(byte * data, uint8_t datlen) { uint16_t CRC = 0xFFFF; // Init CRC uint8_t xor_flag; for (uint8_t n = 0; n < datlen; n++) { CRC = CRC ^ data[n]; for (uint8_t i = 0; i < 8; i++) { if (CRC & 0x0001) { xor_flag = 1; } else { xor_flag = 0; } CRC = CRC >> 1; if (xor_flag) { CRC = CRC ^ 0xA001; } } } return CRC; } void SendCmd( byte * data, uint8_t datlen) { // this is just a test routine to send results Serial Monitor. uint16_t CRC = CalcCRC(data, datlen); for (uint8_t i = 0; i < datlen; i++) { // set TX mode, use the correct Serial (softSerial?) Serial.print(data[i], HEX); Serial.print(' '); } Serial.print(lowByte(CRC), HEX); // This does not match the Example. It could be an error in the manual. Serial.print(' '); // If the device does not respond, reverse the order byte order the CRC Serial.println(highByte(CRC), HEX); // is sent. Send highbyte then lowByte. } |
以 {0x01, 0x03, 0x00, 0x00, 0x00, 0x02} 為例,算出來應該是 0xC4, 0x0B 才對
--
硬體接線
--
程式範例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
#include <SoftwareSerial.h> SoftwareSerial rs485; #define DE 4 byte s[] = {0x60, 0x03, 0x00, 0x00, 0x00, 0x10}; byte r[sizeof(s) + 2]; uint16_t CalcCRC(byte * data, uint8_t datlen) { uint16_t CRC = 0xFFFF; // Init CRC uint8_t xor_flag; for (uint8_t n = 0; n < datlen; n++) { CRC = CRC ^ data[n]; for (uint8_t i = 0; i < 8; i++) { if (CRC & 0x0001) { xor_flag = 1; } else { xor_flag = 0; } CRC = CRC >> 1; if (xor_flag) { CRC = CRC ^ 0xA001; } } } return CRC; } void printHex(uint8_t num) { char hexCar[2]; sprintf(hexCar, "%02X", num); Serial.print(hexCar); } void setup() { pinMode(DE, OUTPUT); Serial.begin(9600); rs485.begin(2400, SWSERIAL_8N1, 14, 12); for ( int i = 0; i < sizeof(s); i++ ) { r[i] = s[i]; } } void loop() { digitalWrite(DE, HIGH); uint16_t CRC = CalcCRC(s, 6); r[6] = lowByte(CRC); r[7] = highByte(CRC); rs485.write(r, sizeof(r)); digitalWrite(DE, LOW); delay(300); for ( int i = 0; i < sizeof(r); i++ ) { printHex(r[i]); } Serial.println(); if (rs485.available() > 0) { while (rs485.available() > 0) { Serial.print(rs485.read()); Serial.print(','); yield(); } Serial.println(); } delay(1000); } |
運行結果
--
注意事項
- 如果選擇的 GPIO 會影響燒錄,那重新開機也會影響程式運作,必須先斷開開機完成才會運作,所以還是需要另外選不會影響的腳位。
--
2,913 total views, 1 views today