Shop OBEX P1 Docs P2 Docs Learn Events
Senior Project help..... — Parallax Forums

Senior Project help.....

Bruk SBruk S Posts: 15
edited 2009-02-18 01:34 in Propeller 1
First, thank you for taking the time to feel my pain....

Ok, guys, here's the scoop. I'm a mechanical engineer here at Sacramento State University and I have been working night and day on this project and I am almost done.

It is a human powered vehicle with a power-assist drive system. Basically its a trike with a motor and its enclosed in a cool looking shell.

We have a 400W brushless DC motor with an onboard controller that only requires a 5K pot to control RPM. It also has a kill lead so that the motor can be shut-off.
We are powering that with a 24V LifePO4 battery that also has a onboard battery management system. I know....doesn't it sound easy already? NOT!
So there is a gearing system that the motor is attached to. A standard bicycle 7-gear magazine linked inline with the main drive motor. There is also a customized
deurailer that is shifted by means of a linear actuator driven by a stepper motor.



So the setup will be as such:


Battery Temperature Sensor
Motor Temperature Sensor
Cabin Temperature Sensor
Speed Sensor

Voltage Sensor
Current Sensor

USB Data Logger
Accelerometer

LCD (4x20)

We are using the propellor to keep track of everything.

Based on the input from the speed sensor, which is simply a hall-effect sensor counting the time between pulses, the value will be compared to a small table
that will determine what the desired gear should be at that speed. For example: gear 1 is from 0-7 miles per hour, gear 2 is from 7 to 11 mph and so on up to gear 5.

If the desired gear is less than the current gear than it will shift down: send correct pulses to the actuator to turn in the correct
direction a set number of steps. Before shifting, the motor kill leads are closed by a relay to insure there is no torque being applied to the gears (to prevent chain slippage).


So we wanted to have a cog dedicated to this process of monitoring and shifting the gears.


Using a 12-bit ADC (MX1270) we will be monitoring a Voltag, Current and the 3 Temperature sensors. These values will then be displayed on the LCD. There will also be conditional statements
that will test these values to be within limits, otherwise the motor will shut-off. Safety.

Ultimately ALL of these values will be logged real-time onto a USB data logger every 30 seconds. The accellerometer is there only for a cool-factor or perhaps to limit shifting based on tilt angle.




Ok, hopefully that did not turn you away.

So. Everything works.
BUT....

Each section only works by itself. Not all together as a unit.

I wanted to run say the shifting in Cog 1, the other sensors and LCD display on Cog 0, and Data logging on Cog 3 (or any order)

When I attempted to run the LCD with the Voltage, Current, and 3 temps sensors on one cog and the gear shifting on another, it totally trips out.
I get garbage on the LCD and the shifting does crazy stuff.....I am slowly starting to lose it guys...this stuff is sooooo frustrating. And on top of that the final presentating is next thursday. Everything has to work by then....

Please...

Please....please...help...


I have attached some of my files to see if any of you can help me fix this. The main reason why we chose the Prop was so that we can have true multiprocessing.



jumpin.gif
«1

Comments

  • CannibalRoboticsCannibalRobotics Posts: 535
    edited 2008-12-10 15:24
    I have not looked at the code but as a general observation, my expirence·is that·this kind of·problam lives in memory overlaps. Make sure you are dedicating enough stack space to your modules.
    Jim-

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Signature space for rent, only $1.
    Send cash and signature to CannibalRobotics.
  • Bruk SBruk S Posts: 15
    edited 2008-12-10 15:33
    When you do get a chance to look at it, check the file called Main.spin. There I have just two other objects/modules that are being called and I've allocated a stack size of 500 for each. I'm not sure, but I think that it's enough. Also, does the fact that both of the objects being called write to the same LCD make a difference? I figured since the LCD is connected to the same output pin, the propeller would share the it between its cogs and not garble it with simultaneous data....that's the most technical solution I can come up with....

    Appreciate the input CannibalRobotics...
  • pgbpsupgbpsu Posts: 460
    edited 2008-12-10 16:21
    @Bruk S

    You could be onto something with the suggestion in your last post. If you have 2 cogs both talking to the LCD, unless you manage who talks when, you could easily have interleaved data arriving at the LCD which would could come out like garbage. I've never done this with and LCD, but I frequently use the Prop Serial Terminal. If two cogs happen to send serial data to P30/P31 at the same time, the data get trashed.

    I think CannibalRobotics's suggestion is a good one, but I'd also look carefully at which cogs are writing to the LCD when and avoid collisions.

    Best of luck.
    pgb
  • Bruk SBruk S Posts: 15
    edited 2008-12-10 16:31
    I was fearing that you'd say I might be right...cuz I'm not sure how to fix that.

    I was thinking....is there a way I can pass a variable from one cog to the other one so that the other cog can do all the LCD writing? So with the above setup, the file HPV_HEADS_UP_LCD.spin right now only displays the values from the ADC which has the Voltage, Current, and 3 temperature sensors. If I could start that one in a cog and have the Gear_Change.spin start in a different cog, and have the gear value passed to the HPV_HEADS_UP_LCD, then I think that would solve my problem.....

    How do I do that?

    I hope that made sense..
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-12-10 17:43
    Hello Bruk,

    cogs can share global variables just by the variablename ITSELF as long as there methods are in the SAME *.SPIN-File

    this means if you define the variables that should be used by different objects in the same file as you define the objects
    each object can access them even across cogs

    instead of

    PUB main
      
      cognew( HeadsUP, @stack1)
      cognew( Shift,   @stack2)
      
    
    PUB Shift
        Auto_Shift.Start
    
    PUB HeadsUP
        Display.Start 
    
    



    this construction does not follow the cognew-standards of parallax
    the cognew should be done INSIDE the objects (here INSIDE HPV_HEADS_UP_LCD.spin and INSIDE Gear_change.spin)

    then the method main in the file main.spin looks like this

    PUB main
        
        Auto_Shift.Start
        Display.Start
    
    



    inside the file HPV_HEADS_UP_LCD.spin

    VAR
      Long stack1[noparse][[/noparse]500]
    
    
    PUB Start  
      cognew( Main, @stack1)
    
    
    



    and inside the file Gear_change.spin

    VAR
      Long stack2[noparse][[/noparse]500]
    
    PUB Start
      cognew(Change_gears,@stack2)
    
    PUB Change_Gears 'renamed method start
        BS2.start (31,30)                               ' Initialize BS2 
        {if you use the LCD-buffer it's not nescessary to call lcd.start(22, 19_200, 4) anymore}
        'lcd.start(22, 19_200, 4)                        ' Start lcd
    
        {lcd.cursor will be replaced by a method LCD_Buf_setCursor}
        'lcd.cursor(0)                                   ' Cursor off
    
        {lcd.backLight(true) will be replaced by a method LCD_Buf_Setbacklight(true)}
        lcd.backLight(true)
            
        Current_Gear  := 1                                'Initialize current gear to 1st gear
        Desired_Gear  := 1
    .....
    ....
    
    
    



    By this way the stackspace will be allocated the right way


    If you want to use variables across objects or *.SPIN-files you can pass the pointer of the variable to the other object
    but i think it is easier to to it this way

    LCD-Issue:
    Another Idea is to create a Send_Data_to_LCD-object and define it in the main.spin-file
    This object would work with a characterbuffer

    This Send_Data_to_LCD-object ONLY reads out the buffer and sends the data to the LCD
    and this object is the ONLY one who sends data to the LCD

    ALL other parts of the program just WRITE to the characterBUFFER

    If you can define fixed and different areas on the LCD for the two things HPV... and Gear_change nothing will go across anymore
    if both objects use the same area (Row-columm on the LCD) you might get a mixed or overlapping output
    of characters but not completely rubbish

    this characterbuffer is simply an array of bytes
    and has to be defined in main.spin

    VAR
    byte LCD_Buffer [noparse][[/noparse]80] ' for a 4x20 LCD

    character in first row first columm LCD_Buffer[noparse][[/noparse]0] := ....

    character in third row second columm
    LCD_Buffer[noparse][[/noparse]40 + 2] := ....

    which is [noparse][[/noparse](RowNr - 1) * 20 + Columm]

    you would start an Update_LCD-method in its own cog

    to keep the serial traffic low inside this method a check if any of the 80 bytes has changed would be done and only if this is the case
    the method sends out the buffercontent again

    best regards

    Stefan

    Post Edited (StefanL38) : 12/10/2008 6:06:30 PM GMT
  • Bruk SBruk S Posts: 15
    edited 2008-12-10 18:04
    Ok, all of that makes sooooo much sense......oh except the last part about the buffer thingy, I'm gonna have to look at that again over some cereal....(hard-core brain food). I've only been working with Spin for a few weeks now and I've been soaking it up.

    Thank you very much for your time and I will definitely correct those issues and report back.
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-12-10 18:33
    Hello Bruk,

    I did some SUBSTANTIAL corrections in my posting ! Please re-read it.

    For the LCD-Buffer: every call of an LCD-method like

      lcd.gotoxy(19, 0)
      lcd.decx(current_gear, 1)
    
    
    



    will be replaced by calls to methods that write into the buffer

    the example above
    will be replaced by a method like

    LCDBuffer.WriteDecx(19,0,current_gear,1)

    This method combines the commands gotoxy and decx
    PUB WriteDecx(X,Y,Value,P4)

    x=columm and y= row
    would be calculated to an offset y * 20 + x = 0 * 20 + 19 = 19

    then the method would write into the arraybuffer starting at offset 19

    if you have more questions about the LCD-Buffer-construction post it here

    best regards

    Stefan
  • Ken PetersonKen Peterson Posts: 806
    edited 2008-12-10 22:01
    Just from a mechanical engineer point of view: You say you will cut power to the motor while shifting. Does this bike have a free-wheel mechanism? If so, you will need to turn the chain while shifting, just not at full torque. Perhaps if you try running the motor at reduced torque while shifting instead of cutting it completely?

    Also, from an electrical engineer point of view: Is your to the Prop consistent and well regulated? Have you made sure there are no surges or voltage dropouts due to the motor?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·"I have always wished that my computer would be as easy to use as my telephone.· My wish has come true.· I no longer know how to use my telephone."

    - Bjarne Stroustrup
  • Bruk SBruk S Posts: 15
    edited 2008-12-10 22:24
    Hey Ken,

    The chain linking the motor to the rear wheel is engaged when the motor is spinning and free-wheel when it is not. The chain will still be turning due to the momentum of the rear wheel as it is fixed with the rear wheel so there are no troubles while shifting. All I can control is the ON/OFF of the drive motor since I'm tripping the kill of the motor via a relay. This momentary cuts off power to the motor just enough time to shift and it will engage as soon as the relay is opened. The only side affect is that it will jerk a slight bit when the motor is turned back on. As far as the regulation of the prop, well I'm hoping the on-board regulator would be enough. I have two batteries, one large 24V 20AH LifePO4 battery for the main drive motor and a small 12V 1.2Ah battery that I will use to power the Prop and the Stepper motor. I was told I can directly connect the 12V battery source to the Prop without much problem, I think I will put a small resistance in line so that the Prop only sees about 9V, just to be on the safe side and keep from having to cool the regulator. Again I have no control over the external drive motor so I'm not even gonna concern myself with it.....


    I'm trying to implement Stefan's suggestion, but for some reason I'm having some issues. I will post the code after I get out of class...

    Again thanks to all of you who have responded. You guys have really helped me solve some of the issues...
  • Bruk SBruk S Posts: 15
    edited 2008-12-11 06:16
    Guys, I'm having some difficulty in writing a new object just for writing to the LCD.

    The dilemma being this:
    One cog calls on the object LCD_Write so that it can write to the LCD
    At the same time, there will be another cog with a process that will call on the same object to write something else.
    Aren't I going to run into the same problem of the two cogs trying to write to the LCD? Maybe I'm not understanding how the object call is going to be executed.

    Really I want to do is process the Voltage, Current, and 3 Temperature sensors in one cog, get their values via the ADC and store that information into a variable so that I can 1. Display it on the LCD and 2. Store it into the Data logger.

    In another cog I want the speed sensor monitored and gears changed accordingly and with that I want to pass the speed value and the gear value to be stored into a variable that can be passed to again the LCD and to the Data logger.

    I understand that I might have to use pointers to reference address locations, but thats about where my knowledge ends.... I'm not exactly sure how to implement that in code...

    Again I appreciate your guys' help....I'm just kinda getting discouraged a bit.

    On a positive note, I was able to successfully modify my code and now I have multiple cogs running with different objects started in them....yay!!

    I need that EASY button right about now...
  • Ken PetersonKen Peterson Posts: 806
    edited 2008-12-11 12:10
    If you are sharing an object that controls the LCD, and you are accessing it from different cog processes, then you should have a mutex of some sort to make sure they aren't trying to access the resource at the same time. Perhaps you can provide functions in your LCD object to "check out" and "check in" the resource, using locks internally to manage the mutex.

    I imagine each access to the lcd takes several steps and these steps need to be atomic, meaning they must not be interleaved by different processes. Once an LCD udpate by one process begins, it must be completed before the other process begins an LCD update.

    I'm not 100% sure whether this is your problem, but I suggest looking into this.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·"I have always wished that my computer would be as easy to use as my telephone.· My wish has come true.· I no longer know how to use my telephone."

    - Bjarne Stroustrup
  • Bruk SBruk S Posts: 15
    edited 2008-12-11 15:27
    New idea....

    I have an object called LCD_Write

    in it I have defined a method that does the writing, called
    PUB Write(col,row,value,width)
    
    


    in the object Gear_Change, there is also a new method called

    PUB Show_Gear : gear
    gear := current_gear
    
    



    so my idea was to call this function in a loop from somewhere in LCD_Write so that it can update the gear value periodically since it returns the current gear value.

    so from LCD_Write
    OBJ
       gear : "change_gear"
    
    PUB Display_stuff | temp_gear
    
    Repeat
       temp_gear := gear.show_gear
       write(19, 0, temp_gear, 1)
    
    



    Ok, logically it made sense....at least to me, but actuality...ummmmm...NO Good.

    Am I just slow? Is there something I'm missing? Is the call out in the repeat section trying to start its own version of Gear_Change? Should I pass something? Are pointers involved? Will you help me?

    I need a miracle....
    
    
    Post Edited (Bruk S) : 12/11/2008 3:32:19 PM GMT
  • Ken PetersonKen Peterson Posts: 806
    edited 2008-12-11 16:32
    I'll see if I can have a closer look at your system after I get out of work. In the mean time I have a bit of advice: When using objects, only have an object responsible for one thing. Your LCD object should know nothing about gears or motors. Your gear and motor objects need know nothing about the LCD. Don't mix responsibilities together.

    I would approach it by having an object for each piece of hardware you have, and then tie them together with a main program. Perhaps you can group some of your objects into bigger objects, but keep it hierarchical.

    Have your main object query each object for its parameters, and then send the information to the display. Then you don't have to worry about sharing your display and it's easier to keep track of different threads of execution.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·"I have always wished that my computer would be as easy to use as my telephone.· My wish has come true.· I no longer know how to use my telephone."

    - Bjarne Stroustrup
  • Bruk SBruk S Posts: 15
    edited 2008-12-11 16:39
    Ken, that was the original intention. In fact every object works perfectly when loaded independently. Its just now that I'm trying to integrate everything by a single call object that I'm having all these problems. I needed it to be a Plug-n-Play, but its been more like Plug-n-Pray.....

    I thank you again for your time.
  • AribaAriba Posts: 2,690
    edited 2008-12-11 16:44
    BrukS

    I think your on the rignt way now. It's the best if one Object collects all values to display from the other objects, and then send it all together to the LCD.

    >.ummmmm...NO Good
    Can you describe a little bit more, what you get? The code looks not bad, perhaps your to fast amd not to slow, because you send data to the LCD and give it no pause to display. You can add a short delay:

    OBJ
       gear : "change_gear"
    
    PUB Display_stuff | temp_gear
    
    Repeat
       temp_gear := gear.show_gear
       write(19, 0, temp_gear, 1)
       waitcnt(clkfreq/4+cnt)
    
    



    Or you send the data only if the value changes:
    OBJ
       gear : "change_gear"
    
    PUB Display_stuff | temp_gear, old_gear
    
    Repeat
       temp_gear := gear.show_gear
       if temp_gear <> old_gear
          write(19, 0, temp_gear, 1)
          old_gear := temp_gear
    
    



    Andy
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-12-11 18:00
    Hello Bruk,

    another concept for displaying data is to code methods that will return a value

    'inside your Gear_change.spin-file
    
    VAR
      long  Current_Gear
    
    PUB Start
    ..
        lcd.gotoxy(0, 0)
        lcd.str(string("HPV-08       GEAR: #"))
        
        lcd.gotoxy(19, 0)
        lcd.decx(current_gear, 1)
        
    ...
    
    



    the variable current_gear contents what it's name is

    if you add a simple PUB-method to your Gear_change.spin-file

    
    PUB Get_CurrentGear : Gear
    
      Gear := Current_Gear
    
    
    



    you can call this method from your main.spin-file to get the value of current_gear out of the Auto_Shift-object into the main.spin-file


    in your main-.spin.file you defined

    OBJ
    
      Display      :  "HPV_HEADS_UP_LCD"
      Auto_Shift   :  "Gear_Change"
      
    
    



    and with tis definition you can call for example

      MyVariable := Auto_Shift.Get_CurrentGear
    
    



    at the moment your HPV_HEADS_UP_LCD.spin-file does most of the LCD-output

    transfer ALL LCD-OUTPUT-code to main.spin (i.e. definition of the object

    lcd : "debug_lcd"

    calls for LCD start, init etc. etc.


    there is some fixed text and the sensors values and here you do the same

    delete your definition of the local variables
    spd_sensor, cur_sensor, vol_sensor, mtemp_sensor, btemp_sensor, ctemp_sensor, value

    of PUB main in the HPV_HEADS_UP_LCD.spin-file

    and define them as GLOBAL variables

    instead of
    PUB Main | spd_sensor, cur_sensor, vol_sensor, mtemp_sensor, btemp_sensor, ctemp_sensor, value
    
    
    



    write

    VAR
      long spd_sensor
      long cur_sensor
      long vol_sensor 
      long mtemp_sensor
      long btemp_sensor 
      long ctemp_sensor
      long value
    
    PUB Main 'no local variables
    
    
    



    and add NEW PUB-methods that give back values in the HPV_HEADS_UP_LCD.spin-file

    PUB Get_spd_sensor : speed
      speed := spd_sensor
    
    PUB Get_cur_sensor : current
      current := cur_sensor
    
    PUB etc. etc
    
    



    these methods GIVE BACK values

    Then you can call ALL these methods inside your main.spin-file in a loop

    if the definition of the LCD-object and all LCD-output code is in main.spin you can code

    
      lcd.decx(Auto_Shift.Get_CurrentGear)
    
      lcd.decx(Display.Get_cur_sensor)
     and all the cursor positioning
      'etc. etc.
    
    



    as the object "Display" does no longer send data to the LCD
    you should NAME it something like "GET_ADC_Sensor_values"

    that its name is SELF-EXPLAINING what happens inside the object

    best regards

    Stefan
  • Bruk SBruk S Posts: 15
    edited 2008-12-17 07:36
    Everyone thank you very much for all of your help. I finally was able to get everything functioning exactly how they were required to. Yesterday was an awesome day, we actually had live data being logged on the USB as we took the power assisted HPV (human powered vehicle) out for a test run.


    Anyway, the only drawback was that the data logger was pretty inconsistent. I'm not sure if the issue was with our prob board or the USB drive, but sometimes it does not record any data even though the lights are flashing and it does not always work initially. And sometimes I have to have the computer plugged in to the prop-board and load the program into RAM and then disconnect the computer for the data-logger to work. Well no worries the logging is only for collecting data and then its a free run after that.

    One question or assistance I need is determining how to increase my sampling rate on the USB. We were trying to log speed and current draw, but it is pretty slow. It seems to record once every 2-3 seconds which seems pretty slow....is that normal? Can I speed it up? Because it records a speed of 0 and then the next speed is at 5mph which really seems to jump a considerable amount seeing that our acceleration is pretty weak. So any ideas?

    Thanks in advance again....

    We will be posting some YOUTUBE footage of the project soon so you guys can see what you helped out on....
  • TJHJTJHJ Posts: 243
    edited 2008-12-17 08:01
    Confirming we are "Data logging" to a USB stick drive, through the parallax one?

    Check that you are adding a 0 to the end of your data log string, or you could be writing the entire buffer for no reason, adding a significant and inconstant delay. I can seem to find the code for where it is actually data logging, to look at it, sorry if its right there, just tired.

    TJ

    Post Edited (TJHJ) : 12/17/2008 8:11:37 AM GMT
  • Bruk SBruk S Posts: 15
    edited 2008-12-17 08:07
    Logging on the USB stick. The LCD screen also displays the data at much much faster rate. In fact the pause delay for my repeat loop to collect data is set to clkfreq/10+cnt

    After several trial and error attempts, the same repeat loop that collects data and writes to the USB stick is set at clkfreq/3+cnt. Otherwise the USB does not log. I don't know if that is an inherent property of the logger, but I would assume that the speed at which it could write to the flash memory would be much faster than once every 2-3 seconds though...
  • Bruk SBruk S Posts: 15
    edited 2008-12-17 08:43
    Ok TJ, I'll try it.

    But I'm a bit confused oh how....

    Here is my calling function that actually collects the data and sends it to the USB.writedata function.

    
    PUB Sensor_Collect_LOGGED| value, temp
        
      repeat value from 1 to DATAPOINTS              
          
          Current_gear_num := get_current_gear
          write(19, 0, Current_gear, 1, int)
          USB.Write_Data(Current_gear_num)
          
          '------------------------Speed----------------------
              
            spd_sensor := speed  'THIS VALUE (SPEED) IS UPDATED IN A DIFFERENT METHOD IN THE SAME OBJECT
            write(4, 1, spd_sensor, 4, flt)
             
            temp := FS.FloatToString(speed)
            USB.Write_Speed(temp)
    
            '------------------------Current--------------------      
            cur_sensor := adc.get_reading(cur)
            write(4, 2, cur_sensor, 4, int)
    
            USB.Write_Data(cur_sensor)
            
            '------------------------Voltage--------------------
            volt_sensor := adc.get_reading(vol)
            write(4, 3, volt_sensor, 4, int)
    
            USB.Write_Data(volt_sensor)
            
            
            
            '------------------------Motor Temp-----------------
            mtemp_sensor := adc.get_reading(mtemp)
            write(14, 3, mtemp_sensor, 5, int)
    
            USB.Write_Data(mtemp_sensor)
            
            '------------------------X-Tilt (left/right)--------
            x_tilt := tilt.x_tilt 
            write(14, 1, x_tilt, 5, int)
            USB.Write_Data(x_tilt)
            
            '------------------------Y-Tilt (forward/back)------
            y_tilt := tilt.y_tilt 
            write(14, 2, y_tilt, 5, int)
    
            USB.Write_Data(y_tilt)
            usb.insertline
                           
          waitcnt(clkfreq/5+cnt)
      USB.done
    
    




    And this is the object that calls the USB data logging. Actaully its a different object which in itself calls on another object which is the USB Data Logger object from the Object Exchange.....

    CON
    
      _clkmode  = xtal1 + pll16x                            ' use crystal x 16
      _xinfreq  = 5_000_000
      clk_freq   = 80_000_000
      
    '--------IO Pins-----------
    
    '  rxUSB   = 0    ' Receive Data    <-- 27937.5 (TXD) white
    '  txUSB   = 1    ' Transmit Data   --> 27937.4 (RXD) green
    
      LF            = 10                                    ' line feed
      CR            = 13                                    ' carriage return
    
      LCD_PIN   = 8                                         '&#9484;-----------------------------------&#9488; 
      LCD_BAUD  = 19_200                                    '&#9474;For Parallax 4x20 Serial LCD on P8 &#9474;
      LCD_LINES = 4                                         '&#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
      
    
    VAR         
    
      long stack1[noparse][[/noparse]400]
      
    OBJ  
      USB        :       "USB_Driver"
      SNum       :       "Simple_Numbers"
    
      
    PUB Start 
        cognew(main(1,0), @stack1)
    
    PUB Main(txUSB,rxUSB) | i, tester
    
      USB.start(txUSB,rxUSB)' start USB drive
      
      if USB.checkErrorCode == 0
        USB.Wake
        USB.OpenForWrite(string("HPV_scvt.CSV"))
    
      Write_Header
      
    PUB Write_Header
        
        USB.WriteLine(string("HPV Data Log"))
        USB.WriteLine(string("All Rights Reserved, data tabulated below is for informatinal purposes only."))
        USB.writeline(string("CSV file can be open via Notepad or Excel"))
        usb.writeline(string(" "))
        usb.writeline(string("Speed from 0 mph"))
        'usb.writeline(string("GEAR, SPEED, CURRENT, VOLTAGE, MTEMP, X-TILT, Y-TILT "))   
        usb.writeline(string("SPEED, CURRENT, VOLTAGE, MTEMP"))   
       
        waitcnt(clkfreq/5 + cnt)
    
    
    
    PUB Write_Speed(speed)   
        
         USB.Write(speed)
         usb.write(string(","))
          
         waitcnt(clkfreq/5 + cnt)
    
        
    PUB Write_Data(sample)
      
           
         USB.Write(Snum.decx(sample,4))
         usb.write(string(","))
          
         waitcnt(clkfreq/5 + cnt)
    
    PUB InsertLine
        USB.Writeline(" ")
    
    PUB Done
        usb.writeline(string(" "))
        usb.writeline(string(" "))
        usb.writeline(string(" "))     
        USB.WriteLine(string("END of DATA COLLECTION"))
        USB.writeline(string("-------------------------------------------"))
        waitcnt(clkfreq/10 + cnt)
        
        USB.Close(string("HPV_scvt.CSV"))  
        USB.Sleep
        waitcnt(clkfreq + cnt)
        'usb.powerDown
    
    
    



    hope this means anything to you....


    Oh so my confusion.....do I just send it a 0 string via one of the functions? Do I put it somewhere special? Can I just scream it out? Can I get an EASY button?

    Post Edited (Bruk S) : 12/17/2008 8:49:11 AM GMT
  • PliersPliers Posts: 280
    edited 2008-12-17 11:52
    Hey Bruk S.

    Would you please post your final code.

    I have just started learning the propeller code, and I find it helpful to study other peoples code. Especially code that has had input from the group of talented programmers here that have help you with your project.

    An electrical schematic would be nice too.

    Thanks.

    Steve B.
  • TJHJTJHJ Posts: 243
    edited 2008-12-17 18:28
    You have two sets of waitcnt commands going. So you call 6 routines, Write to the USB each waiting 1/5 of a second. Plus one wait at the end. So your total dead wait time is 1.2 seconds + the write time + Sample time + Calculation time, WAGing it would seem to add up to about 2 seconds. I think a better method would be if you have a spare cog.... A repeat that writes data if it is updated or not.

    So something like.

    
    'Have the variables be global so they are updated as they can be, not sure which ones are in your current code, So I listed them all
    VAR
    long Current_Gear_Num, spd_Sensor, Cur_Sensor, Volt_sensor, Mtemp_Sensor, X_tilt, Y_tilt
    PUB Sensor_Collect_LOGGED| value
        
      repeat value from 1 to DATAPOINTS              
          
          Current_gear_num := get_current_gear
          write(19, 0, Current_gear, 1, int)
      
          
          '------------------------Speed----------------------
              
            spd_sensor := speed  'THIS VALUE (SPEED) IS UPDATED IN A DIFFERENT METHOD IN THE SAME OBJECT
            write(4, 1, spd_sensor, 4, flt)
    
    
            '------------------------Current--------------------      
            cur_sensor := adc.get_reading(cur)
            write(4, 2, cur_sensor, 4, int)
    
            
            
            '------------------------Voltage--------------------
            volt_sensor := adc.get_reading(vol)
            write(4, 3, volt_sensor, 4, int)
    
           
            
            
            
            '------------------------Motor Temp-----------------
            mtemp_sensor := adc.get_reading(mtemp)
            write(14, 3, mtemp_sensor, 5, int)
    
            
            
            '------------------------X-Tilt (left/right)--------
            x_tilt := tilt.x_tilt 
            write(14, 1, x_tilt, 5, int)
            
            
            '------------------------Y-Tilt (forward/back)------
            y_tilt := tilt.y_tilt 
            write(14, 2, y_tilt, 5, int)
    
           
                           
          waitcnt(clkfreq/5+cnt)
    
    
    
    ' Call this into a new cog, to let it update as fast as possible.
    Pub Write_Data | Value, temp
    
    Repeat value from 1 to DataPoints
          USB.Write_Data(Current_gear_num)
          
         temp := FS.FloatToString(speed)
         USB.Write_Speed(temp)
    
         USB.Write_Data(cur_sensor)
    
         USB.Write_Data(volt_sensor)
       
         USB.Write_Data(mtemp_sensor)
    
         USB.Write_Data(x_tilt)
    
         USB.Write_Data(y_tilt)
           
         usb.insertline
       
    USB.done
    
    
    
    



    This should separate the calculation time reading ext from your data logging time, IF You have an extra cog, if not I would pull the waitcnt command after each USB write.

    To ensure a 0 terminated string change the to 
    PUB Write_Data(sample)
      
           
         USB.Write(Snum.decx(sample,4))
         usb.write(string("," , 0 )) ' This should add the 0 terminated string to ensure it stops sending data here. 
    
    
    



    Simple numbers should be adding a 0 terminator to the strings as it creates them, as well as floatToString.

    When you say in your previous post you set the wait to clkfreq/3 which wait? The one at the end of the repeat loop? Or the ones in-between each write? I dont really think you need as large of a wait after each write...

    Hope This helps,

    TJ
    m
    PS: You signed up for ME... you had to give up the easy button at the start.. :P , I am a fellow ME at UNR in Reno.

    Post Edited (TJHJ) : 12/17/2008 6:35:00 PM GMT
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-12-17 18:50
    Hello Bruk,

    I wanna thank you for reporting back your progress in the project.

    I was really curious about it. Which way did you do displaying all the values ?

    best regards

    Stefan
  • Bruk SBruk S Posts: 15
    edited 2008-12-17 19:27
    Awesome Awesome Awesome.....YES I did forget that I borrowed my EASY button to the Communication guys about the time I started my second year as an ME....
    I'm studying for a final I'm having shortly, but I will try to make these changes and check it out TJ.


    And Stefan, no problem. I will post more details after the stress has subsided. Right now I'm running on no sleep and everything is hectic. Like I said in my last post, I will have a youtube link for you guys to look at....and I will also post the files.

    Friday I graduate and I'm also gonna get my EASY button back....
  • Bruk SBruk S Posts: 15
    edited 2008-12-17 21:03
    Hi guys, another quick question.

    Twice now I have had to change the output pin assigned to the LCD because the output pin no longer worked. As soon as I switch to a different pin, everything works perhaps a few days later after extensive use, the same issue occurs. In fact yesterday the same thing happened. I now have to find another open output pin to assign to the LCD. I was thinking of putting a resistor inline with the pin, but I thought that was only for inputs? And wouldn't a resistor cause a drop in voltage to the point where the LCD might not register the signals as high enough to be a binary 1? I don't think this is normal. Any ideas?
  • heaterheater Posts: 3,370
    edited 2008-12-18 14:40
    Bruk S said...
    Basically its a trike with a motor and its enclosed in a cool looking shell.

    Interesting project. Do you have some pictures of this beast ?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • sylvie369sylvie369 Posts: 1,622
    edited 2008-12-18 14:50
    Bruk S said...
    Hi guys, another quick question.

    Twice now I have had to change the output pin assigned to the LCD because the output pin no longer worked. As soon as I switch to a different pin, everything works perhaps a few days later after extensive use, the same issue occurs. In fact yesterday the same thing happened. I now have to find another open output pin to assign to the LCD. I was thinking of putting a resistor inline with the pin, but I thought that was only for inputs? And wouldn't a resistor cause a drop in voltage to the point where the LCD might not register the signals as high enough to be a binary 1? I don't think this is normal. Any ideas?

    You're using an LCD powered at 5V, right? There should be a 1K resistor in series from the Propeller output pin to the input to the LCD. I've been using one, and it works just fine. I suspect that you're right in your suspicion that the lack of a resistor is killing your output pins.
  • mcstarmcstar Posts: 144
    edited 2008-12-18 19:22
    Yeah, you need an inline resistor even if you are only driving an input for a 5V devince. The reason? The pins on the LCD are likely to float high especially on start up which means when you first start the prop up (before it starts driving the LCD), it will have up to 5V on that pin. I'd think it should be OK for a while, but perhaps the stress is just too much over time.
  • WookieWookie Posts: 27
    edited 2008-12-18 21:48
    Bruk,

    Just wanted to give a quick hello and to wish you some luck on this project. I am currently a graduate student in ME at Sacramento State and was happy to see another ME take on the Propeller. Hopefully I will get the chance to see your project in person. In the mean time and when you get the chance, could you please post your complete code and some pictures for us to look at?

    Thanks and again, good luck on finals. I just finished my last one on Tuesday. Already, I feel like a new man.

    Joe Roeschen
  • soshimososhimo Posts: 215
    edited 2008-12-18 22:31
    Bruk,
    You definitely need a series resistor if interfacing between 3.3v and 5v on the Prop. There are clamp diodes on the pins that can burn out if too much current is applied which is the reason for the series current limiting resistor. There's a great sticky at the top of this board that gives lots of ideas on how to interface 3.3v with 5v devices.
Sign In or Register to comment.