Arduino Uno, ESP32 – przesyłanie pliku tekstowego z PC na kartę SD przez port szeregowy
Pytanie
przesłanie pliku tekstowego z komputera do arduino i do karty SD
Odpowiedź Sztucznej Inteligencji
Bezpośrednia odpowiedź na pytanie
- Najpewniejszą metodą przesłania pliku tekstowego z komputera do Arduino jest wysłanie jego zawartości przez port szeregowy (USB-COM).
- Arduino odbiera strumień bajtów i zapisuje je do pliku na karcie SD przy użyciu biblioteki
SD.h
lub nowocześniejszej SdFat
.
Kluczowe kroki:
- Aplikacja na PC otwiera plik, nawiązuje łączność szeregową i wysyła dane w małych porcjach.
- Szkic Arduino inicjalizuje SPI i kartę SD, reaguje na komendę START, odbiera dane i po komendzie END zamyka plik.
- Po stronie PC można użyć gotowego terminala z funkcją “Send file” (TeraTerm, RealTerm) lub własny skrypt (Python, C#, Delphi).
Szczegółowa analiza problemu
1. Architektura rozwiązania
PC (nadajnik) ⇄ USB/COM ⇄ Arduino + czytnik SD (odbiornik)
- Medium: UART-USB (typowo 115 200 baud; testy pokazują, że 230 400–921 600 baud działają z
SdFat
na AVR/ESP32).
- Protokół: tekstowe znaczniki START:nazwa.txt, blok danych (<=64 B), END, opcjonalnie CRC32.
2. Sprzęt
Element |
Uwagi |
Płytka AVR (Uno/Nano/Mega) lub ESP32 |
ESP32 dodaje Wi-Fi jako alternatywny kanał transferu. |
Moduł micro-SD 3,3 V z konwerterem poziomów |
Piny SPI: MISO, MOSI, SCK + dowolny CS (D4/D10). |
Karta SD FAT16/FAT32 |
Zalecane SD Formatter 5/6. |
3. Kod – strona Arduino (AVR)
#include <SPI.h>
#include <SD.h>
const byte CS = 10; // Chip-Select SD
File f;
bool rx = false;
void setup() {
Serial.begin(115200);
if (!SD.begin(CS)) { Serial.println("ERR:SD"); while (1); }
Serial.println("READY");
}
void loop() {
if (Serial.available()) {
String s = Serial.readStringUntil('\n'); s.trim();
if (s.startsWith("START:")) {
if (f) f.close();
f = SD.open(s.substring(6), FILE_WRITE);
if (f) { rx = true; Serial.println("OK"); } else Serial.println("ERR:OPEN");
}
else if (s == "END") {
if (rx) { f.close(); rx = false; Serial.println("OK:EOF"); }
}
else if (rx) { f.println(s); Serial.println("K"); } // echa sterujące
}
}
• Bufor można przyspieszyć (f.write(buf, len)
) dla bloków 64–128 B.
• Dla plików > 4 MB warto przejść na SdFat
i “pre-allocate()”.
4. Kod – strona PC (Python 3.x)
import serial, time, zlib, sys
PORT='COM3'; BAUD=115200
FILE='plik.txt'; TARGET='dane.txt'
ser = serial.Serial(PORT, BAUD, timeout=2); time.sleep(2)
def expect(t): # proste oczekiwanie
if ser.readline().decode().strip()!=t: sys.exit("Rx mismatch")
ser.write(f"START:{TARGET}\n".encode()); expect("OK")
with open(FILE,'r',encoding='utf-8') as fp:
for ln in fp:
ser.write((ln.rstrip('\n')+'\n').encode())
expect("K")
ser.write(b"END\n"); expect("OK:EOF")
ser.close(); print("Transfer OK")
W Delphi/Lazarus analogicznie: TComPort.WriteStr
, OnRxChar
.
5. Rozszerzenia i warianty
- ESP32/ESP8266: HTTP POST
/upload
→ SD.open()
– ~1 MB/s przy Wi-Fi N.
- X/Y/ZMODEM: gotowe “Send file” z terminala; minimalny kod na Arduino (
xm_receive()
).
- Połączenie bezprzewodowe BLE lub LoRaWAN – tylko dla małych plików (kilka KB).
6. Diagnostyka
- Brak
READY
→ błąd zasilania SD, sprawdzić CS & poziomy logiczne.
- Plik uszkodzony / brak CR → nie domykasz pliku (
f.close
), zbyt szybkie odłączenie zasilania.
ERR:OPEN
przy dużych plikach → karta w trybie tylko do odczytu lub brak miejsca.
Aktualne informacje i trendy
- Biblioteka SdFat v2.x (Bill Greiman) obsługuje UHS-I i taktowanie SPI 50 MHz na ESP32-S3, skracając czas zapisu o >80 %.
- Coraz częściej stosuje się TinyUSB MSC na RP2040 – mikro-SD jest widoczna jako dysk USB-MSC, co eliminuje potrzebę własnego transferu.
- W projektach IoT popularne jest OTA File-Push (MQTT z payloadem binarnym + SPIFFS/SD).
Wspierające wyjaśnienia i detale
- Arduino pełni rolę „serwera plików” o bardzo małej pamięci. Dlatego zamiast buforować cały plik przesyła się go strumieniowo – podobnie jak woda płynie rurą, a nie jest wlewana najpierw do wiadra.
- Suma kontrolna (
CRC32
) dodana po END
pozwala zweryfikować integralność:
\[
CRC{PC} = \text{zlib.crc32(bytes)};\quad CRC{Arduino} = f.crc32()
\]
- Użycie
Serial.flush()
po stronie PC (Python ser.flush()
) wymusza wysłanie bufora przed kolejnymi operacjami.
Aspekty etyczne i prawne
- Upewnij się, że przesyłane pliki nie naruszają praw autorskich.
- Zachowaj poufność – brak szyfrowania oznacza, że każdy mający fizyczny dostęp do linii RX może podsłuchać treść. Dla danych wrażliwych użyj AES-CBC przed wysyłką.
Praktyczne wskazówki
- Rozpocznij od małego pliku (kilka wierszy), obserwuj log w monitorze szeregowym.
- Dodaj diodę LED sygnalizującą stan RX (miganie przy zapisie) – pozwala szybko zauważyć zawieszenie.
- Przy dużych plikach (>512 KB) zwiększ prędkość do 250–500 kBd lub przejdź na ESP32 Wi-Fi.
- Po zapisie odmontuj kartę (przytrzymaj przycisk reset) przed wyjęciem – zapobiega utracie cache FAT.
Ewentualne zastrzeżenia lub uwagi dodatkowe
- AVR UNO ma tylko 2 kB SRAM – brak miejsca na duże bufory; stosuj zapis bezpośredni lub blok 64 B.
- Karty SD klasy 10 mogą wprowadzać długie (>200 ms) stalle podczas zapisu – w krytycznych zastosowaniach użyj industrial SLC.
- Alternatywa: bezpośrednie włożenie karty SD do czytnika PC; metoda szeregowa jest przydatna, gdy karta pozostaje zamknięta w urządzeniu.
Sugestie dalszych badań
- Implementacja YMODEM na Arduino (
ymodem_receive.ino
) – większe okno transmisji i CRC16.
- Integracja szyfrowania end-to-end (ArduinoCrypto + Python PyCryptodome).
- Test wydajności
SdFat
vs SD.h
na różnych kartach i magistralach SPI-HW vs SPI-DMA (ESP32-S3).
Krótkie podsumowanie
Przesłanie pliku na kartę SD w Arduino sprowadza się do:
- Zbudowania prostego protokołu tekstowego (START/DATA/END).
- Wysłania zawartości pliku przez port szeregowy z aplikacji PC.
- Strumieniowego zapisu w szkicu Arduino przy użyciu biblioteki SD/SdFat.
Metoda jest niezawodna dla plików od kilku bajtów do kilku megabajtów, o ile zadbamy o handshake, małe bufory i poprawne zamykanie pliku. W zastosowaniach wymagających większej szybkości warto przejść na ESP32 i HTTP/FTP upload.
Zadaj dodatkowe pytanie Sztucznej Inteligencji
Zastrzeżenie: Odpowiedzi udzielone przez sztuczną inteligencję (model językowy) mogą być niedokładne i wprowadzające w błąd. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi powinny być zweryfikowane przez użytkownika.