How to start ,stop and restart a method while a program is still running.??
Iam using Autodatalogger by SLRM to log RPM and pressure sensor readings.As I have it in the program it does logg RPM and the pressures continually for 1.0 min.I
can change the logging time prior to starting the program.
What wan't to achieve is to stop and re-start the Datalogger for couple of minutes(as it is now) to logg special events that occur that I need to at that time.
In other words I like to start and stop the Datalogger when necessary.
I tried to start and stop using a button but not successful.That is example: ina[BTN1] == 1 ---> start Datalogger --> cognew(Datalogger,@DataloggerStaclk) and
use the Datalogger Oblects - "stop method" at the end of the required time.This does not work.
I have attached archieved version of my project and The AutoDatalogger Object by SRLM.
I am using the "Memory Stick Datalogger - Prallax ID#27937"
Thanks for your help.
Siri
can change the logging time prior to starting the program.
What wan't to achieve is to stop and re-start the Datalogger for couple of minutes(as it is now) to logg special events that occur that I need to at that time.
In other words I like to start and stop the Datalogger when necessary.
I tried to start and stop using a button but not successful.That is example: ina[BTN1] == 1 ---> start Datalogger --> cognew(Datalogger,@DataloggerStaclk) and
use the Datalogger Oblects - "stop method" at the end of the required time.This does not work.
I have attached archieved version of my project and The AutoDatalogger Object by SRLM.
I am using the "Memory Stick Datalogger - Prallax ID#27937"
Thanks for your help.
Siri


Comments
It looks like when you launch the usb object, it sucks up the last of the cogs, so this code dosen't run at all.
repeat num0 from 1 to 2 num0[num0] := 3_999_999_999 num0 := cnt repeat 1 repeat 60 '1 Minute waitcnt(num0 += clkfreq) 'Seconds USB.stop repeatI suggest you adopt a new MAIN method strategy for keeping track of it all.
VAR long cogon[8], cog[8], pile[2000] ' cog management PUB Start 'Assuming that a 80 MHz core clock is being used, 800 cycles is about 10us. 'waitcnt(800 + cnt) 'Wait for 10us -100 khz PASM 'waitcnt(8_000 + cnt) 'Wait for 100 us -10 khz PASM 'waitcnt(80_000 + cnt) 'Wait for 1ms -1000 hz 'waitcnt(800_000 + cnt) 'Wait for 10 ms -100 hz 'waitcnt(8_000_000 + cnt) 'Wait for 100 ms -10hz human reaction speed 'waitcnt(80_000_000 + cnt) 'Wait for 1000 ms -1hz stop ' stop all cogs if running cogon[0] := (cog[0] := cognew(Read0, @pile[0]) > 0) cogon[1] := (cog[1] := cognew(Read1, @pile[200]) > 0) cogon[2] := (cog[2] := cognew(Read2, @pile[400]) > 0) cogon[3] := (cog[3] := cognew(Read3, @pile[600]) > 0) cogon[4] := (cog[4] := cognew(Read4, @pile[800]) > 0) cogon[5] := (cog[5] := cognew(Read5, @pile[1000]) > 0) cogon[6] := (cog[6] := cognew(Read6, @pile[1200]) > 0) cogon[7] := (cog[7] := cognew(Read7, @pile[1400]) > 0) PUB stop '' Unload timer object - frees a cog if cogon[0]~ ' if object running, mark stopped cogstop(cog[0]) if cogon[1]~ ' if object running, mark stopped cogstop(cog[1]) if cogon[2]~ ' if object running, mark stopped cogstop(cog[2]) if cogon[3]~ ' if object running, mark stopped cogstop(cog[3]) if cogon[4]~ ' if object running, mark stopped cogstop(cog[4]) if cogon[5]~ ' if object running, mark stopped cogstop(cog[5]) if cogon[6]~ ' if object running, mark stopped cogstop(cog[6]) if cogon[7]~ ' if object running, mark stopped cogstop(cog[7])So to integrate it into your code.
'' ================================================================================================= '' ************** Pressure Testing ********************** '' '' con _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq MS_001 = CLK_FREQ / 1_000 REFRESH_RATE = 16_000_000' 80_000_000/5 con SCL = 28 'I2C connections to pressure sensor - MS4515DO SDA = 29 id = $51 'Device Read address ---->provided by OEM data = 13 'data in pin to pin 1 of MAX-7219 clock = 11 'clock signal in pin to pin 13 of MAX-7219 load = 12 'load pulse in pin to pin 12 of MAX-7219 DP = 000000 'decimal point minus = 10 'MAX-7219 display code for a minus (-). rxpin = 19 'Receive pin on the Propeller ---> Datalogger txpin = 18 'Transmit pin on the Propeller ctspin = 17 RevPin = 6 Baud = 19200 Lines = 2 INPIN = 8 'RPM counter PIN from BLDC controller MotorPin = 1 'Motor run/stop ExpSolenoid1 = 23 'Exhalation circuit solenoid connected tp P 23 ---> also the pressure relief valve 1 ExpSolenoid2 = 22 'Exhalation circuit solenoid connected to P 22 ----> also the pressure relief valve 2 IntakeSolenoids = 21 'Opens in inspiration and closes during expiration Vac = 14 obj I2C : "pasm_i2c_driver" Revs : "Debug_Lcd" Seg_7: "7_Seg_LED.Driver_V1.3" term : "fullduplexserial" USB : "Autodatalogger" var long cogon[8], cog[8], pile[2000] ' cog management long RevCounterStack[100] long DisplayStack[100] long ControlStack[100] long waitUntil, inFreq long RPM long pressure, pressure1 long filenameaddr long num0, num1, num2, num3 long DataLoggerStack[100] PUB Main 'Assuming that a 80 MHz core clock is being used, 800 cycles is about 10us. 'waitcnt(800 + cnt) 'Wait for 10us -100 khz PASM 'waitcnt(8_000 + cnt) 'Wait for 100 us -10 khz PASM 'waitcnt(80_000 + cnt) 'Wait for 1ms -1000 hz 'waitcnt(800_000 + cnt) 'Wait for 10 ms -100 hz 'waitcnt(8_000_000 + cnt) 'Wait for 100 ms -10hz human reaction speed 'waitcnt(80_000_000 + cnt) 'Wait for 1000 ms -1hz stop ' stop all cogs if running 'MAKE SURE YOU COUNT TOTAL COGS IN USE. Subobjects use cogs also!!! I2C.Initialize(SCL) ' setup I2C buss (boot pins) '1-cog Revs.init(REVpin, baud, lines) ' start Serial_LCD **** 'Do these use cogs? Seg_7.Start(12,11,13) 'start 7 seg driver **** 'Do these use cogs? pause(10) cogon[0] := (cog[0] := cognew(DataLogger, @DataLoggerStack) > 0) '3-cogs cogon[1] := (cog[1] := cognew(Revolution_Counter, @RevCounterStack) > 0) '1-cog cogon[2] := (cog[2] := cognew(ValveControl, @ControlStack) > 0) '1-cog 'cogon[3] := (cog[3] := cognew(Method3, @pile[600]) > 0) 'cogon[4] := (cog[4] := cognew(Method4, @pile[800]) > 0) 'cogon[5] := (cog[5] := cognew(Method5, @pile[1000]) > 0) 'cogon[6] := (cog[6] := cognew(Method6, @pile[1200]) > 0) 'cogon[7] := (cog[7] := cognew(Method7, @pile[1400]) > 0) pause(10) dira[MotorPin]~~ pause(10) outa[MotorPin]~ 'Start BLDC motor Read_Display_Pressure '1-cog '----Total cogs in use: At LEAST :7 PUB stop '' Unload timer object - frees a cog if cogon[0]~ ' if object running, mark stopped cogstop(cog[0]) if cogon[1]~ ' if object running, mark stopped cogstop(cog[1]) if cogon[2]~ ' if object running, mark stopped cogstop(cog[2]) if cogon[3]~ ' if object running, mark stopped cogstop(cog[3]) if cogon[4]~ ' if object running, mark stopped cogstop(cog[4]) if cogon[5]~ ' if object running, mark stopped cogstop(cog[5]) if cogon[6]~ ' if object running, mark stopped cogstop(cog[6]) if cogon[7]~ ' if object running, mark stopped cogstop(cog[7]) Pub Read_Display_Pressure 'READ AND DISPLAY PRESSURE ON THE 8 SEGMENT led DISPLAY repeat Seg_7.Clear(data,clock,load) 'Clear all digits - 7SegLED display 'read I2C I2C.Start(SCL) I2C.Write(SCL,$51) 'write read address Pressure := I2C.Read(SCL,1) 'read pressure value to variable "Value" Pressure1:= Pressure-31 ' Error correction(31)on initial reading at atmospheric pressure Seg_7.CharOut(data,clock,load,Pressure1) 'send pressure data to 7Seg.LED pause(50) Pub ValveControl 'CONTROL SOLENOID VALVES DURING INSPIRATORY & EXPIRATORY PHASE dira[21..23]~~ 'Set solenoid pins as outputs dira[14]~~ outa[23]~~ repeat If Pressure1 < 0 outa[21]~~ outa[22]~ outa[23]~ outa[14]~ 'Inspiratory phase Pump valve open/bypass valve closed and expiratory valves close 'pause(10) ElseIf pressure1 > 4 outa[21]~ ' Expiratory phase ---> pump valve closes/bypass valve opens. outa[22]~~ outa[23]~~ outa[14]~~ 'BOTH Relief valves @22&23 open 'pause(10) If Pressure1 > 3 'In case of inadvertant pressure rises > 5cm.H2O - pump is bypassed and outa[22..23]~~ outa[14]~~ ' both pressure relief valves opne to AIR pause(200) Pub DataLogger 'DATA LOGGER CODE filenameaddr := string("Pressure.txt") num1 := num2 := num3 := 0 waitcnt(clkfreq*6 + cnt) waitcnt(clkfreq*2 + cnt) USB.init(rxpin, txpin, ctspin, filenameaddr, 10_000) ' (address, digits, title) USB.addfield(@pressure, 2, string("Raw")) USB.addfield(@RPM, 4, string("RPM")) USB.addfield(@Pressure1, 2, string("corrected")) ' USB.start repeat num0 from 1 to 2 num0[num0] := 3_999_999_999 num0 := cnt repeat 1 repeat 60 '1 Minute waitcnt(num0 += clkfreq) 'Seconds USB.stop repeat Pub Revolution_Counter Revs.backLight(true) Revs.cursor(0) ctra := 010 << 26 + INPIN ' counter A in POSedge mode frqa := 1 ' increment 1 per pulse waitcnt(clkfreq + cnt) ' measure the input duty cycle using counters. waitUntil := cnt + REFRESH_RATE repeat phsa := 0 ' reset count registers waitcnt(waitUntil+=REFRESH_RATE) inFreq := phsa * (constant(80_000_000/REFRESH_RATE)) ' read the number of edges; convert to 1 second RPM:=(15*inFreq) Revs.CLS Revs.str(string("RPM :")) 'waitcnt(clkfreq / 200 + cnt) Revs.dec(RPM) pub pause(ms) | t '' Delay program in milliseconds t := cnt - 1088 ' sync with system counter repeat (ms #> 0) waitcnt(t += MS_001) dat {{ Copyright (c) 2009-10 Jon McPhalen (aka Jon Williams) AND Autodataloggeer V 1.0 By SRLM Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. }}But the new code doesn't change the fact that you may be using all 8 cogs and requesting more.
Try to merge two cogs functions into one, and see it it works.
When I calculate that I've used at least 7 cogs, I usually try to knock the code around to maintain my 7 cog use so I always have 1 free.
You are putting many different elements of code together, when you do this, its gets very confusing.
Especially when you are using almost all cogs.
Make a block diagram to help you understand your program flow, and cog usage.
Take a look at one such block diagram I created for my own project that used 4 prop chips, and almost all cogs in them. 32 cogs... hahaha..
http://forums.parallax.com/attachment.php?attachmentid=68222&d=1267464086
the required 2-3 min. but I wan't to re-start again at alater time.
Siri
in that case.
Looks like you repeat this sequence at the end of your code.
Pub DataLogger 'DATA LOGGER CODE filenameaddr := string("Pressure.txt") num1 := num2 := num3 := 0 waitcnt(clkfreq*6 + cnt) waitcnt(clkfreq*2 + cnt) USB.init(rxpin, txpin, ctspin, filenameaddr, 10_000) ' (address, digits, title) USB.addfield(@pressure, 2, string("Raw")) USB.addfield(@RPM, 4, string("RPM")) USB.addfield(@Pressure1, 2, string("corrected")) ' USB.start repeat num0 from 1 to 2 num0[num0] := 3_999_999_999 num0 := cnt repeat 1 repeat 60 '1 Minute waitcnt(num0 += clkfreq) 'Seconds USB.stop filenameaddr := string("Pressure2.txt") num1 := num2 := num3 := 0 waitcnt(clkfreq*6 + cnt) waitcnt(clkfreq*2 + cnt) USB.init(rxpin, txpin, ctspin, filenameaddr, 10_000) ' (address, digits, title) USB.addfield(@pressure, 2, string("Raw")) USB.addfield(@RPM, 4, string("RPM")) USB.addfield(@Pressure1, 2, string("corrected")) ' USB.start repeat num0 from 1 to 2 num0[num0] := 3_999_999_999 num0 := cnt repeat 1 repeat 60 '1 Minute waitcnt(num0 += clkfreq) 'Seconds USB.stop RepeatI repeated the entire PUB Datalogger, but changed the second filename to Pressure2.txt
Another way, neater.
Pub DataLogger 'DATA LOGGER CODE filenameaddr := string("Pressure.txt") num1 := num2 := num3 := 0 waitcnt(clkfreq*6 + cnt) waitcnt(clkfreq*2 + cnt) USB.init(rxpin, txpin, ctspin, filenameaddr, 10_000) ' (address, digits, title) USB.addfield(@pressure, 2, string("Raw")) USB.addfield(@RPM, 4, string("RPM")) USB.addfield(@Pressure1, 2, string("corrected")) ' USB.start repeat num0 from 1 to 2 num0[num0] := 3_999_999_999 num0 := cnt repeat 1 repeat 60 '1 Minute waitcnt(num0 += clkfreq) 'Seconds USB.stop DataLoggerR2 Pub DataLoggerR2 'DATA LOGGER CODE Round2 filenameaddr := string("Pressure2.txt") num1 := num2 := num3 := 0 waitcnt(clkfreq*6 + cnt) waitcnt(clkfreq*2 + cnt) USB.init(rxpin, txpin, ctspin, filenameaddr, 10_000) ' (address, digits, title) USB.addfield(@pressure, 2, string("Raw")) USB.addfield(@RPM, 4, string("RPM")) USB.addfield(@Pressure1, 2, string("corrected")) ' USB.start repeat num0 from 1 to 2 num0[num0] := 3_999_999_999 num0 := cnt repeat 1 repeat 60 '1 Minute waitcnt(num0 += clkfreq) 'Seconds USB.stop RepeatHow many times do you want to run it?
So if looks like you are trying to run the datalogger when you press a button.
And have it log the data to a new file name.
That requires some code modification.. the string filename needs to increment..
Another person needs to help you at this point.
If the string you pass to the datalogger dosen't require anything but a number, you could try that.
Just make a counter, and convert the decimal to string every cycle and feed that as the string for the filename.
You will need to rename the filenames once in an os.
So if ina[BTN1] == 1 is your trigger. .....?
All i require is to run the datalogger with the same file name at different time because I will replace the thumb drive with different one,so the file name and else do not matter.
I hope some one come up with a solution.
Siri
Since you helped me with logging -ve numbres, I came accross anther issue.
Thae code as it is - loggs data for 1.0min and with the command "USB.Stop" the file is closed and the object/?cog - shuts down.
When I wan't log another 1.0 min,I only way I know to do this is to turn off the prop board and power on again,then it will log data for 1.0min.
What I an trying to achive is to re-start the Datalogger at random to logg the data for another minute- without shutting down the whole system.
I have a pump and pressures sensors in the system and I do not want to stop them as I wan't to collect data from them at that instant.
What your code does is to stop and start at specific or pre-determined intervals.
I would like to start at random - example: When a switch is pressed --? ina[BTN1]==1, so when I need to logg data - i will only need to press the button to collect data for 1.0 min. then again at later time.
I hope I explained clearly if not let me know .
Thanks,
Siri
The USB drive is recognised only if it is plugged into the Memory Stick Datalogger(Parallax #27937) and then the prop board is powered.Then I see the power on LED sequence discribed
in the user manual - (green & red flashes alternately x 2sec.) and once the usb drive is removed both LED's are off.If I re-insert the USB drive nothing happens.(no flshing Led's).
May be I need to put a on/off switch to the power line to the Datalogger.Then ? re-start the Autodatalogger object and the Datalogger Method.
I have the Memory Stick datalogger soldered on to the board so I have ordered anothe one then I can test and come up with the solution.
I was reading the Vinculum data sheet which has a reset pin.It also says it can be used to by an external source.On the Memory Stick - there 3 pins labelled- Rest,
Ground,Program.So is it possible to reset the Vinculum chip by pulling the Rest pin to ground(jump the 2 pins) and re-start the datalogger oblect .
Please let me know what your opinion - that is if this can be resolved with software.
Thanks again.
Siri
P.S : Attached is the Memory Stick Datalogger - Documentaion.and Viculum documentation.
I edited the Autodatalogger - object and also edited my program.The data logger only writes the Header - File names only. No data was written.
I also removed the thumb drive and re-inserted and it was not recognized.If the thumb drive is already inserted and then the prop fired - the
data logger only writes the header and no data.
Thanks again for you help.
Siri
Attached is the archived files.
The next question is - the Autudatalogger object does not have "PUB Closefile method or Pub Openfile method.So how do you use " Openfile/Closefile" to open
a new file and close it when data is logged.
The data is logged safely when "stop" method is called as in the Demo program.
Thanks for your help.
Siri
The expected call sequence is
- init
- addfield (1..N)
- start
- stop (optional)
The init method will open the filename at SPIN level (and will add System Clock to the header), addfield will write the relevant header data for each field you add. Finally, start will close the file - at SPIN level - and give control to the PASM part which will open the file and close it again once the stop call has been received. IOW, when you follow the sequence listed above you won't have to worry about opening/closing the file manually. All you do is provide a filename to init.I have been trying to make it work as you sugested,I must be doing something wrong.
Now writes the headder and write one set of data and quits.I have beev trying to log about one minute of data at different times.
Thanks for your help.
Siri
Attached is the archived program and the copy of the Data file.
The manual mentions append mode (default) which suggests that only the first log attempt actually works (otherwise one would expect several header/single log line pairs due to the extra close call). Is there any error indication (e.g. LED) that subsequent log attempts fail (short of instrumenting the code yourself)? That said, you could manually send commands to see if consecutive open/write/close attempts work. Also, in the data logger there is a subroutine called reply which makes an attempt to analyze a potential error code. If so it calls critical_error which could be used to light an LED or something like that.
As for calling it, you start logging with a sequence of init/addfield/start, i.e. call (the original) log_start. Then you wait for however you long you want to log. At this point you call log_stop. For the next logging sequence you repeat this sequence whenever you need it. I don't personally own a data logger of this type so in a way I must rely on your test results. HTH
I tested the code exactly as you advised.I changed the "Data field : name byte "00000000.log" , 0 to ---> name byte "Pressure.txt" , 0 The title of the file remains- "00000000" - the name "Pressure" was not the title of the file.
Although I added 3 more data columns ,they were not named but comma delineation was there.- you can see it on the attached text file which
was logged.
I was monitoring the progress via PST - which showed : 00000000.log
00000001.log etc to 00000000A.log ---> 000000011.log etc.
Thanks for your patience and great help.
Siri
P.S: The Datalogger Overwrites it does not append.
repeat 8 [COLOR="#FF0000"]name[n++][/COLOR] := lookupz((index <-= 4) & $F : "0".."9", "A".."F") [COLOR="#020FC0"]index++[/COLOR]The logfile you sent (00000000.log) shows exactly what I expect with addfield(0, 0, 0), i.e. empty column headers and logging of long[0] (clkfreq) in autowidth mode. The logfile seems to contains 2.89 sec worth of data which is close enough for the intended 3 sec. In case there is a 00000001.log file could you attach it please?Then how do you explain that the column header is still there? The file gets closed (and re-opened) between header emission and actual logging.
Anyway, lets resolve the issues raised by PM first and go from there.