Serial Transfer of Text File from PC to Arduino

I need to make a GPS Simulator to assist in the development of my Predictive Lap Timer Project. I have some data files (Race Technology DL-1 Data Logger) from racing at various tracks, and I realized I could use this data as a great tool to test the Predictive Timer. This way, the GPS Simulator can transmit a “scripted” path running at race speed. Perfect!

However, the data is huge and µC memory is small by comparison. So my GPS Simulator will incorporate an ATMEL 16Mbit AT45DB161D Dataflash to hold all of this data.

To connect the Dataflash chip, I used a SOIC to DIP Adapter. The pins on the chip are actually too wide to fit properly onto the pads of this adapter. The legs needed to be bent inward sligthly in order to work. Soldering the SOIC chip to the adapter required a good magnifying glass and a steady hand.

DataFlash and Arduino

Arduino with DataFlash and SOIC Adapter

I decided to use Microsoft Visual C# 2010 Express for the PC transfer program.

A few minor points about the program:
● The transfer loop has a delay for the dataflash “write operation” time period.
● The “@” character flags the end of the transmission.
● Less than 512-bytes simply fills the dataflash buffer and will be lost upon power-loss.
● The remainder of the page is filled inside the arduino program.

Here is the C# transmit program:

/*
 * Data Transfer PC to Arduino
 * All Rights Reserved
 * James M. Eli
 * 2/25/2012
 * 
 */
using System;
using System.IO;
using System.IO.Ports;
using System.Threading;
using System.Collections;

public class EepromLoader {
    static bool _continue, _transmitReady;
    static SerialPort _serialPort;

    public static void Main() {
        int i;

        Thread readThread = new Thread(Read);

        //set the appropriate serial port properties
        _serialPort = new SerialPort();
        try {
            _serialPort.PortName = "COM20";
        } catch (System.Exception ex) {
            Console.WriteLine("Port Name Exception: ", ex);
        }
        try {
            _serialPort.BaudRate = 19200;
        } catch (System.Exception ex) {
            Console.WriteLine("Baud Rate Exception: ", ex);
        }
        try {
            _serialPort.DataBits = 8;
        } catch (System.Exception ex) {
            Console.WriteLine("Data Bit Exception: ", ex);
        }
        _serialPort.Parity = Parity.None;
        _serialPort.StopBits = StopBits.One;
        _serialPort.Handshake = Handshake.None;
        //set read/write timeouts
        _serialPort.ReadTimeout = 500;
        _serialPort.WriteTimeout = 500;

        try {
            _serialPort.Open();
        } catch (System.Exception ex) {
            Console.WriteLine("Opening Port Exception: ", ex);
        }
        if (_serialPort.IsOpen) {
            Console.WriteLine("Serial Port Open.");

            //read text file
            StreamReader objReader = new StreamReader("C:\\users\\jim\\documents\\p.txt");
            string sLine = "";
            ArrayList arrText = new ArrayList();
            i = 0;
            while (sLine != null) {
                sLine = objReader.ReadLine();
                if (sLine != null) {
                    arrText.Add(sLine);
                    i++;
                }
            }
            objReader.Close();
            Console.WriteLine("Text File Read Complete: {0} lines read.", i);

            _continue = true;
            _transmitReady = false;
            _serialPort.DiscardOutBuffer();
            _serialPort.DiscardInBuffer();
            readThread.Start();
            Console.WriteLine("Waiting for Arduino...");
            //wait for arduino to signal ready
            while (!_transmitReady) ;

            //pump the file out the serial port
            for (i = 0; i < arrText.Count; i++) {
                _serialPort.WriteLine((string)arrText[i]);
                //tweak this delay to accomodate eeprom write time
                Thread.Sleep(50);
            }

            //signal transmission completed
            _serialPort.Write("@");
            //pause allowing arduino to catch up
            Thread.Sleep(500);
            _continue = false ;
            readThread.Join();

            try {
                _serialPort.Close();
            } catch (System.Exception ex) {
                Console.WriteLine("Port Closing Exception: ", ex);
            }
            Console.WriteLine("Serial Port Closed: {0} lines transmitted.", i);

        } else {
            Console.WriteLine("Serial Port Failed to Open.");
        }
        //pause here, preventing command prompt window from closing
        Console.ReadLine();
    }

    //serial port read occurs in this seperate thread
    public static void Read() {
        StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
        while (_continue) {
            try {
                string message = _serialPort.ReadLine();
                Console.WriteLine(message);
                if (message.Contains("Arduino Ready.")) {
                    //flag Arduino ready to receive data
                    _transmitReady = true;
                }
            } catch (TimeoutException) { }
        }
    }

}

Here is the Arduino receiving program:

/*
  DataFlash Eeprom Loader
  James M. Eli
  2/25/2012

  dataflash  arduino
  pin 1  --  pin 11
  pin 2  --  pin 13
  pin 3  --  pin  8
  pin 4  --  pin 10
  pin 5  --  pin  7
  pin 6  --  V (2.5-3.6V)
  pin 7  --  ground
  pin 8  --  pin 12

  DF is 5v tolerant but needs lower. I haven't tried to power it with 5v. You can
  get 3.3v from the Arduino. Other connections for SPI are directly connected.
*/
#include <DataFlash.h>

#define PAGE_SIZE 512
#define BYTES_PER_PAGE 500

bool transfer_complete;
uint32_t bytes_stored;
uint32_t dataflash_page;

void setup() {
  Serial.begin(19200);
  DataFlash.Init();
  bytes_stored = 0;
  transfer_complete = false;
  dataflash_page = 1;
  DataFlash.PageErase(dataflash_page);
  DataFlash.StartWrite(dataflash_page);
  Serial.flush();
  //transmitter in wait loop unitl receiving the following
  Serial.println("Arduino Ready.");
}

void loop() { 
  uint32_t i;
  
  while (!transfer_complete && Serial.available()) {
    uint8_t c;
  
    c = Serial.read();
    //echo character
    //Serial.println(c);
    //terminate flag?
    if (c =='@') {
      Serial.println("Arduino Received EOF Delimiter.");
      //fill remainder of eeprom page
      for (i=0; i<(PAGE_SIZE - bytes_stored%BYTES_PER_PAGE); i++) {
        DataFlash.WriteByte('0');
      }
      delay(15);
      transfer_complete = true;
      break;
    }
    //validate data
    if (c >= '.' && c <= '9' && c != '/') {
      DataFlash.WriteByte(c);
      bytes_stored++;
      //increment page?
      if (bytes_stored%500 == 0) {
        //fill up remainder of current page
        for (i=0; i<12; i++) {
          DataFlash.WriteByte('0');
        }
        delay(15);
        //prepare next page
        dataflash_page++;
        DataFlash.PageErase(dataflash_page);
        DataFlash.StartWrite(dataflash_page);
      }  
    } else {
      c &= 0xf;
      if (c != 0x0a || c != 0x0d || c != 0x00) {
        Serial.print("Rejected: ");
        Serial.println(c, DEC);
      }
    }
  }
}

Here is an Arduino program that displays the DataFlash contents:

// DataFlash Eeprom Loader Test
// All Rights Reserved.
// James M. Eli
// 2/25/2012
#include <DataFlash.h>

//dataflash page size (bytes)
#define PAGE_SIZE 512
#define MAX_DATA 1024

void setup() {
  long total_bytes, page_bytes;

  Serial.begin(19200);
  Serial.flush();
  DataFlash.Init();
  DataFlash.StartRead(1);
  Serial.println("Starting DataFlash Read.");
  delay(500);
  page_bytes = 0;
  for (total_bytes=0; total_bytes<MAX_DATA; total_bytes++) {
    Serial.print(DataFlash.ReadByte());
    if (++page_bytes%20 == 0)
      Serial.println();
    if (page_bytes%PAGE_SIZE == 0) {
      Serial.print(" page: ");
      Serial.println((total_bytes + 1)/PAGE_SIZE, DEC);
      page_bytes = 0;
    }
  }    
  Serial.println();
  Serial.println("Completed DataFlash Read.");
}

void loop() {
}

Advertisements

About Jim Eli

µC experimenter
This entry was posted in Uncategorized and tagged , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s