Access Windows CSV files from a Prop

Attached is a project I've been working on for the past week. It's a Propeller object and a companion Windows PC program that allows Propeller programs to read and write CSV files on the PC. The PC program acts as a server for the Propeller program, running as a client via a serial connection (using FullDuplexSerial). With this facility, a Propeller program can create, append to, and read from CSV files on the PC, using strings, integer, fixed-point, and floating-point data. For safety, the files must all be rooted in a named subdirectory of any file device's root directory and not the root directory itself, but the Propeller program can create any number of subdirectories of that directory. (If you happen to choose "c:/Windows/system32" or somesuch, the consequences are your own fault. I bear no responsibility for stupidity. :) )

Here's a screen capture of the server program in action:
attachment.php?attachmentid=84976&d=1315715623

There are only two things to specify: the active directory and the serial port. Once these are specified, the enable button can be pressed and file transfers can begin. Pressing the Enable button will reset the Propeller, so you will need to have your program saved in EEPROM to use this system.

Documentation for the Propeller client object is embedded in the source code and is AutoDoc (Gold Standard) compatible. See this link for access to the AutoDoc facility:

The demo program exercises most of the client's features, and you should read over it, run it, and understand what's going on before writing your own programs.

Questions and comments, as always, are welcome!

-Phil
“Impossible is just a big word thrown around by small men who find it easier to live in the world they’ve been given than to explore the power they have to change it. Impossible is not a fact. It’s an opinion. Impossible is not a declaration. It’s a dare. Impossible is potential. Impossible is temporary. Impossible is nothing.” –Muhammad Ali
Tagged:

Comments

  • 17 Comments sorted by Votes Date Added
  • edited September 2011 Posts: 0Vote Up0Vote Down
    Phil,

    This is great!

    Several times a day I need to access files from my Prop data logger. Normally I move a SD card from the Prop to the PC. This should free me from the need of stopping data collecting in order to transfer information to the PC.

    I'll try it out (probably tomorrow) and let you know what I think.

    Thanks,

    Daune
  • edited September 2011 Posts: 0Vote Up0Vote Down
    Phil

    I have not tested it, but I am sure it works :)

    Anyhow, good job, and I am sure a lot of people will find this useful!

    Bruce

    Novel Solutions
    Machinery Design • Automation • Product Development • Microcontroller Applications

    Striving To Create A More Productive World Through Applied Problem Solving

    "Necessity is the mother of invention."
    Author unknown, but occassionally attributed to Richard Franck.
  • edited September 2011 Posts: 0Vote Up0Vote Down
    Really slick Phil! Thanks for this.

    OBC
    <br>
  • edited September 2011 Posts: 19,461Vote Up0Vote Down
    Thanks, guys! I've updated both the client and server to v.0.91. On the server side, I discovered that the four bytes representing negative integers and fixed-point numbers were being unpacked and written to the file as unsigned numbers. There was also an issue with round-off for the fixed-point data. These issues have now been fixed. I've also added a "halt" instruction to the server which is sent when the object's stop method is called. This will close all files, and put the server in the "disabled" state, which eliminates having to do this by hand to free the port for uploading new programs to the Propeller chip. It also provides a nice visual indication of when all file data transfers have been completed.

    -Phil
    “Impossible is just a big word thrown around by small men who find it easier to live in the world they’ve been given than to explore the power they have to change it. Impossible is not a fact. It’s an opinion. Impossible is not a declaration. It’s a dare. Impossible is potential. Impossible is temporary. Impossible is nothing.” –Muhammad Ali
  • edited September 2011 Posts: 0Vote Up0Vote Down
    Sounds like some nice updates.

    I will have to set aside some time to check it out.

    Bruce

    Novel Solutions
    Machinery Design • Automation • Product Development • Microcontroller Applications

    Striving To Create A More Productive World Through Applied Problem Solving

    "Necessity is the mother of invention."
    Author unknown, but occassionally attributed to Richard Franck.
  • edited September 2011 Posts: 0Vote Up0Vote Down
    Interesting!

    For some data acquisition projects, this might eliminate the SD card altogether.

    Thanks, Phil!
  • edited November 2011 Posts: 0Vote Up0Vote Down
    Interesting!

    For some data acquisition projects, this might eliminate the SD card altogether.

    Maybe send the data with a pair of XBees, and call it a day. Boy, this would be nice to have. Will have to archive this stuff, just in case the need arises.
  • edited March 2013 Posts: 0Vote Up0Vote Down
    Attached is a project I've been working on for the past week. It's a Propeller object and a companion Windows PC program that allows Propeller programs to read and write CSV files on the PC. The PC program acts as a server for the Propeller program, running as a client via a serial connection (using FullDuplexSerial). With this facility, a Propeller program can create, append to, and read from CSV files on the PC, using strings, integer, fixed-point, and floating-point data. For safety, the files must all be rooted in a named subdirectory of any file device's root directory and not the root directory itself, but the Propeller program can create any number of subdirectories of that directory. (If you happen to choose "c:/Windows/system32" or somesuch, the consequences are your own fault. I bear no responsibility for stupidity. :) )

    Here's a screen capture of the server program in action:
    attachment.php?attachmentid=84976&d=1315715623

    There are only two things to specify: the active directory and the serial port. Once these are specified, the enable button can be pressed and file transfers can begin. Pressing the Enable button will reset the Propeller, so you will need to have your program saved in EEPROM to use this system.

    Documentation for the Propeller client object is embedded in the source code and is AutoDoc (Gold Standard) compatible. See this link for access to the AutoDoc facility:
    The demo program exercises most of the client's features, and you should read over it, run it, and understand what's going on before writing your own programs.

    Questions and comments, as always, are welcome!

    -Phil

    Hi Phil! I am trying to implement your program to modify CSV files on a windows pc and I am having some issues. I am using a propeller demo board connected to my PC using the serial port on the demo board. I have your server program running and when I try to run the client program I keep getting an error of "unable to acess com3", even though my demo board is on and connected to my pc. Would you know why this is happening? Thank you!
  • edited March 2013 Posts: 0Vote Up0Vote Down
    RussM wrote: »
    when I try to run the client program I keep getting an error of "unable to acess com3"

    You need to make sure the com port setting matches the same port as the one used by the Prop Tool to communicate with your Demo Board.

    When you press F7 from the Prop Tool which com port does it use? You'll want to use this same port in Phil's program.
  • edited March 2013 Posts: 0Vote Up0Vote Down
    Duane Degn wrote: »
    You need to make sure the com port setting matches the same port as the one used by the Prop Tool to communicate with your Demo Board.

    When you press F7 from the Prop Tool which com port does it use? You'll want to use this same port in Phil's program.

    I am using COM3. What I don't understand is that when Phil's server program is running I am unable to detect COM3 which is keeping me from compiling my client program.
  • edited March 2013 Posts: 19,461Vote Up0Vote Down
    Russ,

    Is the server program disabled when you try to compile and load the client? If not, you need to do so first. Two programs cannot claim the serial port at the same time.

    -Phil
    “Impossible is just a big word thrown around by small men who find it easier to live in the world they’ve been given than to explore the power they have to change it. Impossible is not a fact. It’s an opinion. Impossible is not a declaration. It’s a dare. Impossible is potential. Impossible is temporary. Impossible is nothing.” –Muhammad Ali
  • edited March 2013 Posts: 0Vote Up0Vote Down
    Phil,

    I should have known that you can't have two programs on the serial port at once. I have the whole thing figured out now. Excellent program. Thank you~

    Edit: I ran into an issue that maybe you could help me with Phil. I tried a simple example of just creating a file and everything works fine.
    CON
    
    
      _clkmode      = xtal1 + pll16x
      _xinfreq      = 5_000_000
    
    
      APIN          = 0
      BPIN          = 1
    
    
    OBJ
    
    
      csv   : "csv_file_client"
    
    
    VAR
    
    
      byte read, write[2]
      
    PUB  start | i, ltr
    
    
      csv.start
      write := csv.open_write(string("Something.csv"))
    

    However, when I try to implement it in my program it does not work. In my program everything after the csv.start command seems to not compile. I tried moving around the csv commands within my code to try and get it to work but to no avail. Am I missing something?
     
    
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
      '_xinfreq = 6_250_000
      
      TX_PIN = 0
      BAUD = 19_200
      MS_001 = CLK_FREQ / 1_000
      CLK_FREQ = ((_clkmode-xtal1)>>6)*_xinfreq
      
      LCD_PIN       = 27
      LCD_BAUD      = 19_200                                    
      LCD_LINES     = 4
      LCD_COLS      = 20
    
    
      ''Size Encoder A Channel(blue) = 1
      ''Size Encoder B Channel(yellow) = 2
      ''Angle Encoder A Channel(blue) = 4
      ''Angle Encoder B Channel(yellow) = 5
      ENCODER_CHANNELA_SIZE   = 1
      ENCODER_CHANNELA_ANGLE   = 4
    
    
    OBJ
      quad_size  :       "QuadDecoder"
      quad_angle  :       "QuadDecoder"
      LCD    :       "FullDuplexSerial"
      sio    :        "FullDuplexSerial"
      f32           : "F32"
      f32_orig      : "Float32Full"
      fs            : "FloatString"
      csv   :"csv_file_client"
    
    
    VAR
    
    
      long offset_size                                          ' example variable that will be accumulated to
      long offset_angle
      long distance
      long temp
      long distance_tick
      long f1
      long fA
      long angle
      long angle_tick
      byte cog
      long stack[90]
      byte highs[200]
      byte lows[200]
      long future_size
      long current_size
      long previous_size
      long detecthighpoint
      long detectlowpoint
      long k
      long j
      long index
      long index2
      long float_highs[200]
      long float_lows[200]
      byte read, write[2] 
    PUB start | i, ltr
    
    
      LCD.start(TX_PIN, TX_PIN, 00, 19_200)    'Initialize FullDuplexSerial.spin
      f32.start
      f32_orig.start
       
      csv.start
      write := csv.open_write(string("Data.csv"))
    
    
      quad_size.start(ENCODER_CHANNELA_SIZE, @offset_size)                    ' start the size encoder
      quad_angle.start(ENCODER_CHANNELA_ANGLE, @offset_angle)   
    
    
      LCD.tx($0C)
      LCD.tx($11)
     
    
    
        LCD.str(string("Size ="))
        LCD.tx($0D)
        LCD.str(string("Angle ="))
        LCD.tx($0D)
    
    
        distance_tick := 0.000983
        distance := 0.0
        angle_tick := 0.144
        angle := 0.0
        current_size := 0.0
        previous_size := 0.0
        detecthighpoint := 0
        detectlowpoint := 1
        k := 0
        j := 0
        offset_size := 0.0                                         ' initialize the accumulator
        offset_angle := 0.0
        index := 0
        
        repeat index2 from 0 to 199
          float_highs[index2] := 0.0
    
    
       repeat while (offset_angle < 2500)
          current_size := f32_orig.FMul(f32_orig.FFloat(offset_size), distance_tick)
          angle := f32_orig.FMul(f32_orig.FFloat(offset_angle), angle_tick)
    
    
          LCD.tx($87)
          LCD.str(fs.FloatToFormat(current_size,13,6))
          LCD.tx($9D)
          LCD.str(fs.FloatToFormat(angle,10,4))
             
          if (current_size < previous_size) AND (detecthighpoint == 1) '(previous size was a high)
            float_highs[i] := previous_size
            k++
            detectlowpoint := 1
            detecthighpoint := 0
          if (current_size > previous_size) AND (detectlowpoint == 1) '(previous size was a low)
            float_lows[i] := previous_size
            j++
            detecthighpoint := 1
            detectlowpoint := 0
               
        previous_size := current_size               
        waitcnt(clkfreq/100 + cnt)
    
    
      
      repeat index from 0 to (k-1) 
        csv.write_float(write, float_highs[index])
        {{LCD.tx($94)                           
        LCD.str(fs.FloatToString(float_highs[index]))
        LCD.tx($BC)
        LCD.str(fs.FloatToString(float_highs[index+1]))
        pause(2000)}}
    
    
      LCD.str(string("Wrote file"))
      pause(2000)
      LCD.tx($0C)
    
    
      csv.close_all 
      LCD.stop
      f32.stop                                             
      f32_orig.stop
      quad_size.stop
      quad_angle.stop
                         
    PUB pause(ms) | t 
     t := cnt 
     repeat ms 
      waitcnt(t += MS_001)     
    
    
    
    
    
  • edited March 2013 Posts: 0Vote Up0Vote Down
    phil, missed thisbefore. what agreat program, a real gem.
    My Prop boards: CpuBlade, TriBlade, RamBlade, www.clusos.com
    Prop Tools (Index)
    Emulators (Index) ZiCog (Z80)
    Prop OS (also see Sphinx, PropDos, PropCmd)
  • edited March 2013 Posts: 19,461Vote Up0Vote Down
    Russ,

    The server has to be running and enabled for your program to get past the csv.start.

    -Phil
    “Impossible is just a big word thrown around by small men who find it easier to live in the world they’ve been given than to explore the power they have to change it. Impossible is not a fact. It’s an opinion. Impossible is not a declaration. It’s a dare. Impossible is potential. Impossible is temporary. Impossible is nothing.” –Muhammad Ali
  • edited March 2013 Posts: 0Vote Up0Vote Down
    Phil,
    I was looking at AutoDoc website but could not find the AutoDoc Gold Standard specs. Perhaps you might like to place a link on your webpage for this?

    For others, here is the link
    http://forums.parallax.com/showthread.php/127233-Automatic-Spin-Program-Documenter-(Online-version-now-available)?highlight=autodoc
    My Prop boards: CpuBlade, TriBlade, RamBlade, www.clusos.com
    Prop Tools (Index)
    Emulators (Index) ZiCog (Z80)
    Prop OS (also see Sphinx, PropDos, PropCmd)
  • edited April 2013 Posts: 0Vote Up0Vote Down
    Hi Phil,

    I have a quick question. Is there any way to insert a carriage return in a CSV file so two sets of data are printed in two separate rows? Something like the following:
      repeat index3 from 0 to i 
        csv.write_float(write, float_highs[index3])
    
    
     'Have next set of data write to next row
      
      repeat index5 from 0 to i
       csv.write_float(write, float_angles[index5])
    
Sign In or Register to comment.