Senior Project help.....
Bruk S
Posts: 15
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.
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.
zip
17K
Comments
Jim-
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Signature space for rent, only $1.
Send cash and signature to CannibalRobotics.
Appreciate the input CannibalRobotics...
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
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..
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
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
inside the file HPV_HEADS_UP_LCD.spin
and inside the file Gear_change.spin
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
Thank you very much for your time and I will definitely correct those issues and report back.
I did some SUBSTANTIAL corrections in my posting ! Please re-read it.
For the LCD-Buffer: every call of an LCD-method like
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
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
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...
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...
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
I have an object called LCD_Write
in it I have defined a method that does the writing, called
in the object Gear_Change, there is also a new method called
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
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
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
I thank you again for your time.
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:
Or you send the data only if the value changes:
Andy
another concept for displaying data is to code methods that will return a value
the variable current_gear contents what it's name is
if you add a simple PUB-method to your Gear_change.spin-file
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
and with tis definition you can call for example
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
write
and add NEW PUB-methods that give back values in the HPV_HEADS_UP_LCD.spin-file
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
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
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....
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
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...
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.
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.....
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
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.
So something like.
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.
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
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
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....
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?
Interesting project. Do you have some pictures of this beast ?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
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.
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
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.