我正在與 Arduino 和 Lora 合作。Arduino A 有相機、收音機和 SD 卡。Arduino B 具有相同的設定,但沒有相機。
目標是將圖片從 A 發送到 B。下面的代碼應該從 SD 卡 A 中讀取 32 個位元組(感謝mmixLinus),并通過 LoRa 發送到 Arduino B,將這 32 個位元組保存到它的自己的SD卡。該檔案將一次發送 32 個位元組,直到其全部 53k 到達。
經過一些故障排除,并認為我正在丟失資料包,我決定計算發送的數量與接收的數量。他們匹配。
我還發送到控制臺每個資料包的位元組數。他們匹配。
但是,保存在接收 SD 卡中的結果檔案比發送 SD 卡上的原始檔案小。它無法使用。
我注意到的是,我期望每個資料包都是 32 位元組,除了最后一個可能更小。但是,即使發送和接收的位元組匹配,我也不確定為什么我的代碼不會占用每個檔案讀取的全部 32 個位元組。
這些是我的主要問題。
- 你能幫我找出我做錯了什么嗎?
- 什么是實作錯誤檢查的理想簡單方法,確保發送的每個資料包在收到時都經過檢查和驗證,并讓發送者知道它可以發送下一個資料包?
這是發件人的代碼。
oFile = SD.open("ring.jpg", FILE_READ); //open source file for read.
long cByteTotal = oFile.size(); //get total bytes
Serial.print("Original size: ");
Serial.println(cByteTotal);
while (cByteTotal > 0) {
int length = cByteTotal < 32 ? cByteTotal : 32;
if (length < 32) {
Serial.println("Sending last packet."); //info
}
oFile.read(cArray, length); //read 32 bytes from file
cArray[length] = '\0'; // terminate the char array
sendMessage(String(cArray)); //send the file via Lora after casting to string
delay(250); // just in case to give time to receiver to process
cByteTotal -= length;
}
oFile.close();
Serial.println("Done Sending.");
void sendMessage(String cArray) {
LoRa.beginPacket();
LoRa.write(cArray.length());
LoRa.write(cArray);
LoRa.endPacket();
}
這是接收方的代碼。
void loop() {
onReceive(LoRa.parsePacket());
}
void onReceive(int packetSize) {
if (packetSize == 0) {
return;
}
packageTotal ;
byte incomingLength = LoRa.read();
String incoming = "";
while (LoRa.available()) {
incoming = (char)LoRa.read();
}
if (incomingLength != incoming.length()) {
// check length for error
Serial.println("LENGHT [ERROR]"); // this does not get triggered, which is good.
return; // skip rest of function
} else {
cFile = SD.open("wimage.jpg", FILE_WRITE);
cFile.print(incoming);
cFile.close();
}
}
我正在使用以下Lora 庫
謝謝您的幫助!
uj5u.com熱心網友回復:
您在這里犯的主要錯誤是您將文??件內容視為字串,您絕對不應該這樣做。一個二進制檔案可以有0x00,字串終止符,這肯定會毀了你的午餐。
您首先需要做的是將 32 位元組塊按應有的方式處理,作為二進制 blob,然后使用write(const uint8_t *buffer, size_t size);. 此外,您正在使用LoRa.write(cArray.length());,它不會做任何事情:它不會告訴 LoRa 庫您正在發送多少位元組,并且接收器無論如何都知道接收了多少位元組。您的函式應如下所示:
void sendMessage(String cArray) {
LoRa.beginPacket();
LoRa.write(cArray, cArray.length());
LoRa.endPacket();
}
接下來,傳輸本身。您正在while回圈傳輸,延遲非常小,至少有兩個原因太小了,并且沒有檢查接收器是否確實收到了塊 #x,并且正確接收了它。這會導致很多問題...
您已經有一個回圈,即 aptly-named loop(),因此您不需要另一個回圈。相反,在內部loop,從卡中讀取 32 個位元組,將它們發送到包含塊號、資料和基本 CRC 的資料包中。例如,添加資料包中的每個位元組,并將其用作 16 位數字,作為資料包的最后 2 個位元組。您將擁有 2 [計數器] 32 [資料] 2 [CRC] 的結構。
然后切換到“等待確認”模式。直到您收到接收器的回復,向您發送 4 個位元組,2 個用于索引,2 個用于 CRC,您什么都不做。如果發回的 CRC 錯誤,則不要增加計數器。如果 CRC 正確,則遞增。然后切換到發送模式。沖洗并重復。
在接收器上,您處于待機模式。當您收到一個資料包時,您計算 CRC 并進行比較——如果它不正確,您將其發回,然后回傳接收模式。如果正確,則將 32 個位元組保存在緩沖區內的正確位置。并回傳索引 CRC。最后你保存。
哦,這是receEIve,不是receive...
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/530471.html
