Transmitting at 433MHz from SD txt file - first characters missing?

Hi, I’m doing a project that involves reading a text file from an SD and then transmitting it via 433MHz RF kit (http://www.ebay.co.uk/itm/161292991774?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l2649) to another Arduino board.

The problem is that the first few characters of the SD file frequently wont be transmitted. I’m unsure as to whether this is a programming error (not giving the SD enough time to be read from before transmission?) or a hardware issue (perhaps the RF kit needs a second to start up for some reason).

I have tried sending a dud message before reading the SD but it doesn’t do anything. If I put some dud characters at the start of the message with the understanding that they would be lost it would solve my problem but I’m curious as to why it is happening in the first place.

My transmit code is as follows (this includes the folly buffer message before reading from SD):

//Connect transmitter facing inwards to pins A3, A4 and A5
//Connect microSD breakout boards as follows:
//
//  5v Pin to 5v Pin
//  GND to GND
//  CLK to Pin 13 (do not worry about LED)
//  DO to 12
//  DI to 11
//  CS to 10
//  CD to nothing.  CD is for and LED light when a microSd is connect and is not necessary for transfers

#include <VirtualWire.h>
#include <SdFat.h>

SdFat sd;
SdFile myFile;

const int led_pin = 11;
const int transmit_pin = A5;
const int receive_pin = 2;
const int transmit_en_pin = 3;
const int chipSelect = 10;
char data;

void setup()
{
    // Initialise the IO and ISR
    vw_set_tx_pin(transmit_pin);
    vw_set_rx_pin(receive_pin);
    vw_set_ptt_pin(transmit_en_pin);
    vw_set_ptt_inverted(true); // Required for DR3100
    pinMode(A3, OUTPUT);
    pinMode(A4, OUTPUT);
    pinMode(A5, OUTPUT);
    digitalWrite(A3, LOW);
    digitalWrite(A4, HIGH);    
    
    vw_setup(3000);       // Bits per sec
    
   Serial.begin(9600);
  while (!Serial) {}  // wait for Arduino
  
  if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt(); // open the file for reading:
  
  if (!myFile.open("sens.txt", O_READ)) {
    sd.errorHalt("File read failed!");
  }
  char buffMsg[] = "########This is a buffer message \n";  
  vw_send((uint8_t *)bufferMsg, 1);
  vw_wait_tx();
  while ((data = myFile.read()) >= 0){
        
    char msg[1] = {data};
  //  delay(0);
    vw_send((uint8_t *)msg, 1);
    vw_wait_tx(); // Wait until the whole message is gone
    delay(50);
}
  // close the file:
  myFile.close();
}

void loop()
{ 
}

The receive code is just the standard affair and works for everything after the first couple of characters and I do not think it is to blame at all.

PS: If there is anything bad about my code or anything of poor form please say. I’m trying to maximise transfer rates as much as possible!

Thanks in advance.

Have you tried printing the characters to the Serial Monitor at the same time as they are sent via wireless. That would enable you to see that the correct data was being recovered from the SD Card.

I presume you have proved that all data sent from one Arduino is correctly received by the other one?

...R

Yep, that’s actually something I should’ve mentioned about the receiver code - it does currently print to the Serial monitor and write to the SD for each byte. That’s how I’ve been checking to see if the start is getting chopped off.

And yup, beyond the initial hiccup of ~6 characters missing all data from a 1Kb test text file has been received and is correct. I can fix it with a buffer message before the initial transfer but I would rather fix the root cause of the problem.

Receiver code is as follows:

//Attach receiver module facing inwards from pins A2 to A5

#include <VirtualWire.h>
#include <SdFat.h>

//Virtual Wire initialisations
const int receive_pin = A4;
const int transmit_en_pin = 7;
const int Vpin = A5;
const int GND = A2;

//SdFat initialisations
SdFat sd;
SdFile myFile;
const int chipSelect = 4;


void setup()
{
    Serial.begin(9600);	// Debugging only
    Serial.println("setup");
    
    // Initialise the IO and ISR
    vw_set_rx_pin(receive_pin);
    vw_set_ptt_pin(transmit_en_pin);
    vw_set_ptt_inverted(true); // Required for DR3100
    pinMode(Vpin, OUTPUT); // Sets up pins for use
    pinMode(GND, OUTPUT);
    digitalWrite(Vpin, HIGH);  // Sets up pin voltage levels
    digitalWrite(GND, LOW);
    
    vw_setup(3000);	 // Bits per sec
    vw_rx_start();       // Start the receiver PLL running

}

void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;

    if (vw_get_message(buf, &buflen)) // If a message is received...
    {       
          if (!sd.begin(chipSelect, SPI_HALF_SPEED)) //  Try to begin communication with microSD
          sd.initErrorHalt(); // If fails then error
    
          if (!myFile.open("RX.txt", O_RDWR | O_CREAT | O_AT_END)) // Try to open file for write
          sd.errorHalt("opening rx.txt for write failed");  // If fails then error
          
          for (int i = 0; i < buflen; i++) //For each received byte...
      {        
          Serial.print((char)buf[i]);
	  myFile.print((char)buf[i]); //Write single byte to to myFile, rx.txt
      }  
          myFile.close();
        }
      }
  char buffMsg[] = "########This is a buffer message \n";  
  vw_send((uint8_t *)bufferMsg, 1);

Fill an array with data. Then, send one byte. Why such a large array, then?

  while ((data = myFile.read()) >= 0){
        
    char msg[1] = {data};
  //  delay(0);
    vw_send((uint8_t *)msg, 1);
    vw_wait_tx(); // Wait until the whole message is gone
    delay(50);
}

Why do you need a new array to hold one character? Why are you reading and sending the data one character at a time? Why are you pausing after each character?

You can use a scalar variable (data) in place of the (useless) array:

    vw_send((uint8_t *)&data, 1);

Use Tools + Auto Format. Your
code is a pain in the
eyes to read, jerking all over
the place like that.

Hooby:
Yep, that's actually something I should've mentioned about the receiver code - it does currently print to the Serial monitor and write to the SD for each byte. That's how I've been checking to see if the start is getting chopped off.

I was talking about the sender code - to see if it correctly retrieves characters before it tries to transmit them.

Maybe the data on the SD Card is incorrect?

...R