Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

uart_tx_file.ino and/or uart_rx_file.ino truncate bytes #253 and #254 of each trame #116

Closed
philippedc opened this issue Jan 17, 2025 · 8 comments
Assignees

Comments

@philippedc
Copy link

philippedc commented Jan 17, 2025

Hi, many thanks for this library and your contribution. There was several threads about transmitting a picture,... I'm trying to get it working with the last library version.
The project is building a camera door bell.
The camera is a ESP32-CAM, the receiver is a Cheap Yellow Display ESP32.
Here is the code for the sender:
`
/*
ESP32-CAM takes photos to save on SPIFFS, and with serial transfert / RS485 wire transfer

From an idea of: http://electroniqueamateur.blogspot.com/2020/07/esp32-cam-gestion-distance-de-la-carte.html
https://gist.github.com/ypelletier/e47f4df32745fbdd7bc6799a42979ba3
RS485 exemple: https://microcontrollerslab.com/rs485-serial-communication-esp32-esp8266-tutorial/

about file transfer: https://github.com/PowerBroker2/SerialTransfer/tree/master
discussion: https://forum.arduino.cc/t/transfer-pictures-from-esp32-cam-to-esp32-via-serial/647488
!!! file transfer v3.1.3 only
IDE version 1.8.16 with Expressif Sytems (ESP32) version 2.0.3
*/

//#define SAVE2SPIFFS // to save photo to SPIFFS

// ===========================
// Enter your WiFi credentials
// ===========================
const char* ssid = "xxxxxx";
const char* password = "yyyyyy";

// wifi
//-------
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
WebServer server(80);

// SDCard
//---------
#include <SPIFFS.h>
#include <FS.h>

// to keep data
//-------------
#include <Preferences.h> // https://randomnerdtutorials.com/esp32-save-data-permanently-preferences/
Preferences pref;

// camera
//----------------
#include "esp_camera.h"
#include "Arduino.h"
#include "soc/soc.h" // Disable brownour problems
#include "soc/rtc_cntl_reg.h" // Disable brownour problems

// file transfer
//----------------
#include "SerialTransfer.h" // https://github.com/PowerBroker2/SerialTransfer/tree/master
SerialTransfer myTransfer;
HardwareSerial Comm(1);

// RS485
//----------------
// note: 2nd Serial with Tx = 15, Rx = 14 to MAX485 Rx & Tx pins
#define REpin 15 // MAX485 RE/DE pins 2 & 3
#define TXpin 14 // MAX485 RO pin 4
#define RXpin 13 // MAX485 DI pin 1
#define RS485Transmit HIGH
#define RS485Receive LOW
#define BAUD_RATE 200000 //962100

#define flashPin 4 // white flash led
#define ledPin 33 // red led
int fileNumber = 0; // jpeg file name index number

//
// SETUP
//_____________________________________________________________________________________________

void setup() {

WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector

// Console
Serial.begin(115200); // Define and start serial monitor
delay(1000);
Serial.println(F("starting..."));

// RS485 Serial communication
Comm.begin(BAUD_RATE, SERIAL_8N1, RXpin, TXpin); // Define and start Comm serial port
myTransfer.begin(Comm);
pinMode(REpin, OUTPUT);
digitalWrite(REpin, LOW);

// camera setup - AI Thinker - ESP32-CAM pins definition
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = 5;
config.pin_d1 = 18;
config.pin_d2 = 19;
config.pin_d3 = 21;
config.pin_d4 = 36;
config.pin_d5 = 39;
config.pin_d6 = 34;
config.pin_d7 = 35;
config.pin_xclk = 0;
config.pin_pclk = 22;
config.pin_vsync = 25;
config.pin_href = 23;
config.pin_sscb_sda = 26;
config.pin_sscb_scl = 27;
config.pin_pwdn = 32;
config.pin_reset = -1;

config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG; // YUV422|GRAYSCALE|RGB565|JPEG
config.frame_size = FRAMESIZE_QVGA;
/* UXGA(1600x1200)
SXGA(1280x1024)
XGA(1024x768)
SVGA(800x600)
VGA(640x480)
CIF(400x296)
QVGA(320x240)
HQVGA(240x176)
QQVGA(160x120)
*/
config.jpeg_quality = 12; // 10-63 ; plus bas = meilleure qualité
config.fb_count = 1; // nombre de frame buffers

esp_err_t err = esp_camera_init(&config);
if(err != ESP_OK) {
Serial.printf("Camera error 0x%x", err);
return;
}
sensor_t * s = esp_camera_sensor_get();

// wifi
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED) delay(500);
Serial.print(F("IP address: ")); Serial.println(WiFi.localIP());

// web server
server.on("/delete", HTTP_GET, handleDelete);
server.on("/clic", HTTP_GET, handleSave);
server.onNotFound(handleNotFound);
server.begin();
Serial.println(F("Web server started."));

// SPIFFS init
//if(SPIFFS.format()) Serial.println(F("SPIFFS erased successfully."));
if(SPIFFS.begin(true)) Serial.println(F("SPIFFS OK"));
else Serial.println(F("SPIFFS error!"));

// get photo index number
pref.begin("parameters", false);
fileNumber = pref.getUInt("num", 0);

} // end of setup

//
// LOOP
//_____________________________________________________________________________________________

void loop() {
server.handleClient();
}

//============================================================================================
// list of functions
//============================================================================================

//
// html Save - Take a photo and save it to SDCard
//____________________________________________________________________________________________

void handleSave(void) {

camera_fb_t * fb = NULL; // frame buffer

fb = esp_camera_fb_get(); // prise de la photo
if(!fb) {
Serial.println("Failed to take a photo.");
return;
}
uint16_t fbSize = fb->len; // keep size of fb
uint8_t *fbFile = fb->buf; // keep picture frame in file

// save photo to SPIFFS
#ifdef SAVE2SPIFFS
char fileName[20] = ""; // picture file name .jpg
sprintf(fileName, "/%d.jpg", fileNumber++); // file name creation
pref.putUInt("num", fileNumber); // keep the file index number
if(SPIFFS.exists(fileName)) SPIFFS.remove(fileName);
File file = SPIFFS.open(fileName, FILE_WRITE);
if(!file) Serial.println("SPIFFS error!");
else {
//file.write(fb->buf, fb->len);
file.write(fbFile, fbSize);
Serial.printf("Photo saved: %s", fileName);
Serial.print(F(" size= ")); Serial.println(fbSize);
}
file.close();
#endif

// photo file serial transfer
// 1- transfer mode & send fbSize
digitalWrite(REpin, RS485Transmit); // RS485 transmit mode
myTransfer.sendDatum(fbSize); // Send fbSize

// 2- define number of packets to transmit
uint8_t dataLen = MAX_PACKET_SIZE -2; // Reserve two bytes for current file index
uint16_t numPackets = fbSize / dataLen; // the number of packets
if(fbSize % MAX_PACKET_SIZE) numPackets++; // Add an extra transmission if needed

// 3- send all data within the file across multiple packets
for(uint16_t i=0; i<numPackets; i++) { // Send all data within the file across multiple packets
uint16_t fileIndex = i * MAX_PACKET_SIZE; // Determine the current file index

// define data length for the last packet if file length is not an exact multiple of MAX_PACKET_SIZE-2
if((fileIndex + (MAX_PACKET_SIZE -2)) > fbSize) dataLen = fbSize - fileIndex;

// 4- send packets
uint8_t sendSize = myTransfer.txObj(fileIndex); // Stuff the current file index
sendSize = myTransfer.txObj(fbFile[fileIndex], sendSize, dataLen); // Stuff the current file data
myTransfer.sendData(sendSize, 1); // Send the current file index and data

Serial.print(i); Serial.print(F(" packet#")); Serial.print(fileIndex);
Serial.print(F(" len= ")); Serial.print(dataLen); 
Serial.print(F(" sendSize= ")); Serial.println(sendSize);
delay(100);

} // end of for

esp_camera_fb_return(fb);
digitalWrite(REpin, RS485Receive); // RS485 stop transmit mode

// web message
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
server.send(200, "text/html", "");
WiFiClient client = server.client();
server.sendContent("

Une nouvelle photo a été prise.

");
server.sendContent("

Retour à la liste des fichiers

");
} // end of handleSave()

//
// LoadFromSPIFFS() - operations on sdcard
//____________________________________________________________________________________________

bool LoadFromSPIFFS(String path) {

String dataType = "text/plain";
if(path == "/") PrintDirectory();
else {
if(path.endsWith(".src")) path = path.substring(0, path.lastIndexOf("."));
else if(path.endsWith(".htm")) dataType = "text/html";
else if(path.endsWith(".css")) dataType = "text/css";
else if(path.endsWith(".js")) dataType = "application/javascript";
else if(path.endsWith(".png")) dataType = "image/png";
else if(path.endsWith(".gif")) dataType = "image/gif";
else if(path.endsWith(".jpg")) dataType = "image/jpeg";
else if(path.endsWith(".ico")) dataType = "image/x-icon";
else if(path.endsWith(".xml")) dataType = "text/xml";
else if(path.endsWith(".pdf")) dataType = "application/pdf";
else if(path.endsWith(".zip")) dataType = "application/zip";

File file = SPIFFS.open(path.c_str());
if(!file) return false;

if(server.hasArg("download")) dataType = "application/octet-stream";
if(server.streamFile(file, dataType) != file.size()) Serial.println("Sent less data than expected!");

file.close();

}
return true;
} // end of LoadFromSPIFFS()

//
// PrintDirectory()
//____________________________________________________________________________________________

void PrintDirectory() {

server.setContentLength(CONTENT_LENGTH_UNKNOWN);
server.send(200, "text/html", "");
WiFiClient client = server.client();
server.sendContent("

Prise de photo

");
server.sendContent("

");
server.sendContent("

Contenu de la carte SD

");

File dir = SPIFFS.open("/");
File entry = dir.openNextFile();
while(entry) {
Serial.print(F("\tFILE: ")); Serial.print(entry.name());
Serial.print(F("\tSIZE: ")); Serial.println(entry.size());
String output = " ";
output += entry.name();
// add a delete button
output += "
        <a href = /delete?url=";
output += entry.name();
output += "> [Supprimer]
";
server.sendContent(output);
entry = dir.openNextFile();
}
dir.close();
} // end of PrintDirectory()

//
// html Delete
//____________________________________________________________________________________________

void handleDelete() {

if(server.args() == 0) {
returnFail("Mauvais arguments?");
return;
}
String path = "/" + server.arg(0);
Serial.print(F("deleting: ")); Serial.println(path);

//SPIFFS.remove((char *)path.c_str());
SPIFFS.remove(path);

// delete confirmation
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
server.send(200, "text/html", "");
WiFiClient client = server.client();
server.sendContent("

Le fichier a été supprimé

");
server.sendContent("

Retour à la liste des fichiers

");
} // end of handleDelete()

//
// html display
//____________________________________________________________________________________________

void handleNotFound() {
if(LoadFromSPIFFS(server.uri())) return;
String message = "Action imprevue\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for(uint8_t i = 0; i < server.args(); i++) {
message += " NAME:" + server.argName(i) + "\n VALUE:" + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
Serial.print(message);
} // end of handleNotFound()

void returnOK() {
server.send(200, "text/plain", "");
}

void returnFail(String msg) {
server.send(500, "text/plain", msg + "\r\n");
}

`

@philippedc
Copy link
Author

philippedc commented Jan 17, 2025

Here is the receiver:

`
/*
RS485 Serial transmit from ESP32-CAM to ESP32-CYD

about serial2 for CYD: witnessmenow/ESP32-Cheap-Yellow-Display#75
about MAX485 to MAX485: https://microcontrollerslab.com/rs485-serial-communication-esp32-esp8266-tutorial/

the RGB led pins are used for RS485 connexion:
17 TX2, 16 RX2, 4 RE

*/

// parameters
//--------------
const String VERSION = "v1.0"; // code version
#define DEBUG 1 // allow console messages

// ===========================
// Enter your WiFi credentials
// ===========================
const char* ssid = "xxxxx";
const char* password = "yyyyyy";

// wifi
#include <WiFi.h>
#include <WebServer.h>
WebServer server(80);

// TFT display
//----------------
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
#include <TJpg_Decoder.h> // https://github.com/Bodmer/TJpg_Decoder

//#include <LovyanGFX.hpp>
//#include "lgfx_ESP32_2432S028.h"

byte chosenTextFont = 0; // 0 or 2 or 4
const byte textFont[] = { 4, 1, 2, 2, 1, 2 }; // 3 combinaisons font + size
#define backgroundColor TFT_BLACK
#define textColor TFT_WHITE
byte screenRotation = 3;

int16_t dw = 320;
int16_t dh = 240;

// sd card part
#include "SPI.h"
#include "FS.h"
#include "SD.h"

// pinup
//-----------------
// sd card pins: default VSPI pins
#define SD_MOSI 23
#define SD_MISO 19
#define SD_SCK 18
#define SD_CS 5

// file transfer
//----------------
#include "SerialTransfer.h" // https://github.com/PowerBroker2/SerialTransfer/tree/master
SerialTransfer myTransfer;

#define BAUD_RATE 200000
#define RS485Transmit HIGH
#define RS485Receive LOW
#define REpin 4

char imageBuffer[5000];
uint16_t loopCount = 0;
uint16_t byteCount = 0;
uint16_t imageSize = 0;

//
// SETUP
//_____________________________________________________________________________________________

void setup() {

// console
Serial.begin(115200);
delay(1000);

// RS485
Serial2.begin(BAUD_RATE); // RS485 IO: 17 TX2, 16 RX2
myTransfer.begin(Serial2);
pinMode(REpin, OUTPUT);
digitalWrite(REpin, RS485Receive); // init receive

// TFT display
tft.init();
tft.fillScreen(backgroundColor);
tft.setRotation(screenRotation);
//tft.setRotation(0);
/*
Normally strings are printed relative to the top left corner but this can be
changed with the setTextDatum() function. The library has #defines for:

TL_DATUM = 0 = Top left
TC_DATUM = 1 = Top centre
TR_DATUM = 2 = Top right
ML_DATUM = 3 = Middle left
MC_DATUM = 4 = Middle centre
MR_DATUM = 5 = Middle right
BL_DATUM = 6 = Bottom left
BC_DATUM = 7 = Bottom centre
BR_DATUM = 8 = Bottom right

L_BASELINE = 9 = Left character baseline (Line the 'A' character would sit on)
C_BASELINE = 10 = Centre character baseline
R_BASELINE = 11 = Right character baseline
*/

tft.setSwapBytes(true);
tft.setTextColor(textColor);
tft.setTextFont(textFont[chosenTextFont]);
tft.setTextSize(textFont[chosenTextFont +1]);
tft.setTextDatum(MC_DATUM);
tft.drawString("Moniteur Video", 160, 120 -80);
tft.drawString(VERSION, 160, 120 -40);
//tft.drawString("", 160, 120);
//tft.drawString("", 160, 120 +40);
//tft.drawString("", 160, 120 +80);
delay(2000);
tft.fillScreen(TFT_BLUE);

TJpgDec.setJpgScale(1); // The jpeg image can be scaled by a factor of 1, 2, 4, or 8
TJpgDec.setCallback(tft_output); // The decoder must be given the exact name of the rendering function above

dw = tft.width();
dh = tft.height();

// start sd card: must be placed AFTER tft and ts setup
//------------------
// info: https://www.programmingelectronics.com/esp-32-sd-card-test-and-hardware-setup/
//pinMode( SD_CS, OUTPUT );
SPI.begin(SD_SCK, SD_MISO, SD_MOSI, SD_CS);
//if(!SD.begin(SD_CS)) Serial.println(F("Card Mount Failed"));
// to allow 6 "open files" instead of the default 5
if(!SD.begin(SD_CS, SPI, 4000000, "", 7)) Serial.println(F("Card Mount Failed"));
else {
uint8_t cardType = SD.cardType();
if(cardType == CARD_NONE) Serial.println(F("No SD card attached"));
else {
Serial.print(F("SD Card Type: "));
if(cardType == CARD_MMC) Serial.println(F("MMC"));
else if(cardType == CARD_SD) Serial.println(F("SDSC"));
else if(cardType == CARD_SDHC) Serial.println(F("SDHC"));
else Serial.println(F("UNKNOWN"));
Serial.printf("SD Card Size: %lluMB\n", SD.cardSize()/(1024*1024));
ListDir(SD, "/", 0);
}
}

} // end of setup

//
// LOOP
//_____________________________________________________________________________________________

void loop() {
unsigned long tempo = millis();
static unsigned long memoTempo = tempo;

if(myTransfer.available()) {
memoTempo = tempo;
if(!myTransfer.currentPacketID()) {
myTransfer.rxObj(imageSize);
#ifdef DEBUG
Serial.println(imageSize);
#endif
}
else if(myTransfer.currentPacketID() == 1) {
#ifdef DEBUG
Serial.print(++loopCount); Serial.print(": bytesRead: "); Serial.println(myTransfer.bytesRead);
#endif
for(uint16_t i=2; i<myTransfer.bytesRead; i++) {
imageBuffer[byteCount] = (char)myTransfer.packet.rxBuff[i];
byteCount++;
}
} // end of test myTransfer.currentPacketID() == 1
} // end of test myTransfer.available()

if((tempo > (memoTempo + 1000)) && (loopCount > 0)) {

Serial.print(F("byteCount= ")); Serial.println(byteCount);
Serial.print(F("imageSize: ")); Serial.println(imageSize);

// save to sdcard
String path = "/pic.jpg";
if(SD.remove(path)) Serial.println(F("File deleted"));
else Serial.println(F("no file to delete"));
File file = SD.open(path, FILE_WRITE);
if(!file) Serial.println(F("Failed to open file for writing"));
//file.write((unsigned char *)imageBuffer, byteCount);
file.write((unsigned char *)imageBuffer, imageSize);
file.close();
Serial.printf("Record file: %s\n", path);

// read picture from sdcard
//char adresse2[] = "/12.jpg";
TJpgDec.drawSdJpg(0, 0, path);
//tft.drawJpg(imageBuffer, imageSize, 0, 0, dw, dh);
/*
uint16_t w = 0, h = 0;
TJpgDec.getJpgSize(&w, &h, (const uint8_t)*imageBuffer, imageSize);
Serial.print(F("width = ")); Serial.print(w); Serial.print(F(", height = ")); Serial.println(h);

TJpgDec.drawJpg(0, 0, imageBuffer, imageSize);
//tft.pushImage( 0,0,320,240, (uint16_t*)imageBuffer.c_str());

*/
// reset counters
//Serial.print(F("Photo published size: ")); Serial.println(imageSize);
loopCount = 0;
byteCount = 0;
memset(imageBuffer, 0, sizeof(imageBuffer));
ListDir(SD, "/", 0);
} // end of test tempo
} // end of loop

//============================================================================================
// list of functions
//============================================================================================

//
// tft_output() called by TJpgDec.setCallback(tft_output);
//____________________________________________________________________________________________

bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap) {

if( y >= tft.height()) return 0; // Stop further decoding as image is running off bottom of screen
tft.pushImage(x, y, w, h, bitmap); // This function will clip the image block rendering automatically at the TFT boundaries
return 1; // Return 1 to decode next block
}

//
// sd card functions
//____________________________________________________________________________________________

void ListDir(fs::FS &fs, const char *dirname, uint8_t levels) {
Serial.printf("Listing directory: %s\n", dirname);

File root = fs.open(dirname);
if(!root) {
Serial.println(F("Error to open directory"));
return;
}
if(!root.isDirectory()) {
Serial.println(F("Not a directory"));
return;
}

File file = root.openNextFile();
while(file) {
if(file.isDirectory()) {
Serial.print(F("\tDIR : "));
Serial.println(file.name());
if(levels >0) ListDir(fs, file.name(), levels -1);
}
else {
Serial.print(F("\tFILE: "));
Serial.print(file.name());
Serial.print(F("\tSIZE: "));
Serial.println(file.size());
}
file = root.openNextFile();
}
} // end of ListDir()

void ReadFile(fs::FS &fs, const char *path) {
Serial.printf("Reading file: %s\n", path);

File file = fs.open(path);
if(!file) {
Serial.println(F("Failed to open file for reading"));
return;
}

Serial.print(F("Read from file: "));
while(file.available()) Serial.write(file.read());
file.close();
} // end of ReadFile()

void WriteFile(fs::FS &fs, const char *path, const char *message) {
Serial.printf("Writing file: %s\n", path);

File file = fs.open(path, FILE_WRITE);
if(!file) {
Serial.println(F("Failed to open file for writing"));
return;
}
if(file.print(message)) Serial.println(F("File written"));
else Serial.println(F("Write failed"));
file.close();
} // end of WriteFile()

void AppendFile(fs::FS &fs, const char *path, const char *message) {
Serial.printf("Appending to file: %s\n", path);

File file = fs.open(path, FILE_APPEND);
if(!file) {
Serial.println(F("Failed to open file for appending"));
return;
}
if(file.print(message)) Serial.println(F("Message appended"));
else Serial.println(F("Append failed"));
file.close();
} // end of AppendFIle()

void RenameFile(fs::FS &fs, const char * path1, const char * path2) {
Serial.printf("Renaming file %s to %s\n", path1, path2);
if (fs.rename(path1, path2)) Serial.println(F("File renamed"));
else Serial.println(F("Rename failed"));
}

void DeleteFile(fs::FS &fs, const char * path) {
Serial.printf("Deleting file: %s\n", path);
if (fs.remove(path)) Serial.println(F("File deleted"));
else Serial.println(F("Delete failed"));
}

void CopyFile(fs::FS &fs1, const char * path1, fs::FS &fs2, const char * path2) {
Serial.printf("copying: %s to %s\n", path1, path2);
File file1 = fs1.open(path1, FILE_READ);
if( fs2.open(path2, FILE_READ)) Serial.printf("%s yet exists, delete it first\n", path2);
File file2 = fs2.open(path2, FILE_WRITE);

size_t n;
uint8_t buf[64];
while((n = file1.read(buf, sizeof(buf))) > 0) {
file2.write(buf, n);
}
}

`

@philippedc
Copy link
Author

I cannot receive a viewable jpg photo.
I do not understand what is wrong, it would be possible to compare the jpg file content before transmit and once receive, however I cannot configure the SD card at the same time with Serial transfer...

However if I rename the pic.jpg as pic.txt it looks like a jpg file.
Something strange :
I first transmit the image buff size: myTransfer.sendDatum(fbSize);
Once received, I do not get the same value between fbSize and the number of bytes transmitted during the for(uint16_t i=2; i<myTransfer.bytesRead; i++)
for instance on the console I can get:
byteCount= 3416
imageSize: 3442

I guess here is the problem

@philippedc
Copy link
Author

philippedc commented Feb 1, 2025

I get time to investigate, for instance to compare the jpeg file before serial transmit and after.
There are very few différences between them, but there from time to time a lack of data transmitted.
Here is the file comparaison to illustrate:

Image

On the left the received file

I cannot understand why from time to time some characters are missing....

@philippedc
Copy link
Author

the baud rate is 57600 for a distance of 10cm.

@philippedc
Copy link
Author

philippedc commented Feb 1, 2025

I've done more tests with several photos and it is always the same characters that are not transferred, the 2 first are those I circle in yellow on the above picture.
I've tried to downgrade V3.1.3 to 3.0.6 (older versions do not compile with expressif 2.0.3) but it doesn't change the issue

@philippedc
Copy link
Author

I'm sorry to write so much messages, but I really would like to solve this issue.

I decide to base64 code the data before transfer, and decode it once receive. There are still missing characters, but now we know what:

each trame bytes #253 (and as 2 characters are missing I suppose #254 as well) are cut off.

Never the less my code is directly coming from file transfer exemple, I use back the file transfer exemples and find the same issue:

Image

@philippedc philippedc changed the title jpg photo Serial transmit (again!!!) doesn't work uart_tx_file.ino and/or uart_rx_file.ino truncate bytes #253 and #254 of each trame Feb 2, 2025
@PowerBroker2
Copy link
Owner

Thanks for bringing this to my attention - there was a slight bug in the example TX sketch. This should work instead:

#include "SerialTransfer.h"


SerialTransfer myTransfer;

const int fileSize = 2000;
char file[fileSize] = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestib";
char fileName[] = "test.txt";


void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  
  myTransfer.begin(Serial);
}


void loop()
{
  myTransfer.sendDatum(fileName); // Send filename
  
  uint16_t numPackets = fileSize / (MAX_PACKET_SIZE - 2); // Reserve two bytes for current file index
  
  if (fileSize % MAX_PACKET_SIZE) // Add an extra transmission if needed
    numPackets++;
  
  for (uint16_t i=0; i<numPackets; i++) // Send all data within the file across multiple packets
  {
    uint8_t  dataLen   = MAX_PACKET_SIZE - 2;
######################################################################################
######################################################################################
### This changed: ###
    uint16_t fileIndex = i * dataLen; // Determine the current file index
######################################################################################
######################################################################################

    if ((fileIndex + (MAX_PACKET_SIZE - 2)) > fileSize) // Determine data length for the last packet if file length is not an exact multiple of MAX_PACKET_SIZE-2
      dataLen = fileSize - fileIndex;
    
    uint8_t sendSize = myTransfer.txObj(fileIndex); // Stuff the current file index
    Serial.println();
    Serial.println(sendSize);
    Serial.println(dataLen);
    sendSize = myTransfer.txObj(file[fileIndex], sendSize, dataLen); // Stuff the current file data
    
    myTransfer.sendData(sendSize, 1); // Send the current file index and data
    Serial.println();
    Serial.println(sendSize);
    Serial.println(dataLen);
    Serial.println();
    delay(100);
  }
  delay(10000);
  Serial.println();
  Serial.println();
}

Side note:

I've seen many people do this when posting issues and I never understood: how is it possible to post code on an issue without formatting it, look at it after posting, and not realize the unformatted code looks horrendous? How come it never occurred to you that the code should be formatted like how I did above? Why do I need to tell everyone to format code in issues???

Sorry for the rant, but I'm always bewildered when people do this and would like to understand.

@PowerBroker2 PowerBroker2 self-assigned this Feb 2, 2025
@philippedc
Copy link
Author

Many thanks for the correction.

I'm sorry, I do not understand how github works.
I never successed how to format code, even when I use the appropriate button it does not operate as expected. And as there is no way to preview...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants