Mark,
Servo motors require that you send them a control pulse roughly 50 times a second or they shut themselves off until they get another control pulse (I think to save power in case they're out of range ... when they're used in a radio controlled vehicle). The PAUSE 20 provides the 20ms pause between pulses so you get roughly 50 per second. The PULSOUT statement actually sends the pulse whose width is determined by the 2nd number in the statement. The FOR/NEXT just provides the looping (for 121 times in this case).
Note: In a previous question, you had a FOR/NEXT and DO/LOOP combined. They have to be nested. You can't have them overlapped. In other words, FOR / DO / LOOP / NEXT is allowed and DO / FOR / NEXT / LOOP is allowed, but DO / FOR / LOOP / NEXT is forbidden.
·· Thanks for your post. It helps me understand better what's happen in the line commands so I can try and explain it to the team this afternoon.
So PAUSE can be used at least two ways then, yes?
1) As a true pause between FOR/NEXT (etc.) commands where 1000 =· second pause) as below
FOR motormovementtime = 0 TO 60 ······ PULSOUT 15, 650 ······ PULSOUT 13, 850 ······ PAUSE 20
NEXT
PAUSE 500·· ' (500·means 500 ms, or 1/2 second)
FOR motormovementtime = 0 TO ·······PULSOUT 15, 650 ······ PULSOUT 13, 850 ······ PAUSE 20
NEXT
2) As a PAUSE between·pulses in a PULSOUT command (to motors, etc.)
FOR motormovementtime = 0 TO 60 ······ PULSOUT 15, 650 ······ PULSOUT 13, 850 ······ PAUSE 20
NEXT
I now understand that DO/LOOP commands and FOR/NEXT commands have to be 'nested' (one inside the other.) Thanks! Let's say we want to loop a FOR/NEXT command then, to make the motors loop through a sequence twice (3 times,·4 times, etc.) What do we enter for the 'UNTIL' or 'WHILE' command value, and where, because the program·prompts us for it when we try to enter the subroutine below. Because the FOR/NEXT commands are 'nested' within the DO/LOOP command as you suggested, is it in the correct sequence below?
DO ·· FOR motormovementtime = 0 TO 120 ······PULSOUT 15, 650 ······ PULSOUT 13, 850 ······PAUSE 20 ···NEXT
LOOP ---> UNTIL?· --->·WHILE? (*assume we want the sequence above to loop three times)
Mark,
In the case you mention, it's better to use two nested FOR / NEXT loops. You need another variable for the outer loop. The DO/WHILE/UNTIL loop is used for cases where the loop is conditional on something else like an I/O state ("IN1 == 0") or a complex relationship ("x < 5 and a <> 0"). In your case, you'd have:
FOR i = 1 TO 100
FOR motormovementtime = 0 TO 120
PULSOUT 15,650
PULSOUT 13,850
PAUSE 20
NEXT
PAUSE 1000 ' Wait a second between movements
NEXT
·· The (attached) 'robot in rocket' program runs great. It records data, moves forward 1 meter, backs up 40 cm, turns 45 degrees, records data, and repeats the program again perfectly. Thanks everyone!
The robot is supposed to·turn on and run·when it's deployed form the rocket. Prior to flight we set the Parallax board switch to "2" and·then install it in the payload bay. We have a simple switch mechanism that turns power on when the robot comes out of the rocket. However, when we run the robot on the floor (by flipping·our switch "on" instead of attaching it directly to the computer using the serial cord), here's what happens:
1) Green Parallax power light comes on. A-OK
2) Red light on Parallax Datalogger light comes on. It does·NOT blink 'red-green-red-green'' but stays red. The light inside the flash drive does not turn on.
3) When we push the small black 'reboot' button on the Parallax board,·the Datalogger light stays red, the flash drive light blinks fast (indicating that it's initializing), then the Datalogger and flash drive blink back and forth red-green-red-green-red-green showing us that data is being acquired (the first program step.)
4) Next (last in the program sequence) the robot moves forward, backward, turns, then collects data all over again as it's supposed to.
Here's the glitch (and a big one!): we will not be a mile up in the air when·the robot·comes out of the rocket! Therefore, we cannot push the black reset button on the Parallax board to make the program run. I'm fairly certain there must be a program 'fix' (cycle the initialization sequence through twice, for example?) We just spent the better part of our pratice·today trying to 'fix' the program so·it·runs independently of direct connection to the computer (by reading the book, commenting out various·line commands, etc.) Unfortunately, we struck out.
Andrew Tim, and/or Tyler should be posting a similar note sometime soon. Any ideas how to remedy this by modifying the program? I'm stumped (but optomistic!)
·· We tried your idea of 'nesting' one FOR/NEXT command inside the other at today's practice to effectively loop a subroutine, and it worked marvelously! The kids had a great time trying it, then experimenting with nested FOR/NEXT commands inside of multiple FOR/NEXT commands, just to see what would happen. You're teaching some eager young minds excellent programming (and I wish I was as clever at this as everyone else is. I'm discovering that it WILL take time!) Thanks, Mike!
· We're switching ON an external power supply which feeds power to the a PCB (didn't know what that meant before..!) It's essentially a small headphone-type jack into which we insert a thin plastic dowel. This shuts off the power until the dowel is physically pulled out. When the robot ejects from the rocket, the plastic dowel is pulled out, turning power on. One of the parents wired it and I believe the wires from the servomotor lead into, and out of it. Andrew has the robot and he's an hour away.
ANDREW: Please check where this 'jack' is wired on the robot and post a reply to Mr. Bateas and I.
Bruce, I think·rearranging the·program sequence somehow might make it work. last night I ran a version of the program (motors on first, data collection next) and the motors came on instantly, the datalogger initialized, but data wasn't sent to the flash drive...
Should we post a picture of the 'bot here on the forum? Would that help?
I·have a roomful of energetic students right now but I will check in·throughout the day, as always.
···Attached is·a photo and·a brief·explanation of the robot's 'power-on mechanism'. I'll post more details photos if folks would like, so you can see the 'switch' in more details. I think the glitch is in the initialization sequence, though, because when we run an earlier verison of the program, the motors run and the Datalogger initializes the flash drive (but records no data.)
I've looked how the "headphone-type jack" is wired into the robot. It is connected mid-way between the 6-9 VDC input and the 9v battery. I've also attached a few pictures of the robot, if you want them.
2) Red light on Parallax Datalogger light comes on.
It does NOT blink 'red-green-red-green'' but stays red.
The light inside the flash drive does not turn on.
I've experienced a similar problem with my Datalogger.
Here is my solution:
Restart:
DEBUG "Restart", CR
PAUSE 400 ' Allow Time To Settle
HIGH TX ' Initialize Transmit Line
LOW RTS ' Take Vinculum Out Of Reset
PAUSE 500 ' Allow Time To Settle
DEBUG "Done!", CR, "Synchronizing..."
idx_1 = 0
DO
SEROUT TX\CTS, T9600, [noparse][[/noparse]"E", CR] ' Sync Command Character
GOSUB Get_Data ' Get Response
PAUSE 450
idx_1 = idx_1 + 1
IF iobyte = $0d THEN GOTO Found_E
IF idx_1+1 > 5 THEN GOTO Restart
LOOP UNTIL ioByte = $0D ' Wait For Carriage Return
Essentially it limits the number of passes thru the loop
looking for an 'E', then forces the Vinculum to go thru the Reset
sequence again.
This seems to work very reliably in my application.
I'd change the following lines in your initialization code:
PAUSE 10 ' 1000 = 1 second. 500 allows 1/2 second to settle
HIGH TX ' Initialize Transmit Line
LOW RTS ' Take Vinculum Out Of Reset
PAUSE 500 ' Allow 1/2 Second To Settle
You may have some contact bounce when the the pin is pulled that
connects the battery. The longer PAUSE of 500 may help if that is the case.
phil
Post Edited (phil kenny) : 2/18/2008 4:21:53 PM GMT
·· Thanks for the post! Did you see the photos of pur robot that Andrew posted (above)? Where exactly in the program does your 'restart' subroutine go? Does it replace any command lines, or is it in addtion to what's already there?
Do the four lines (below) that you suggested we change in the initialization sequence replace line commands that are already there? I don't have the program or the robot in front of me (but I can't wait to get home to try this.)
Andrew:Try·Mr. Kenny's suggested changes to the program, run the robot with the changes, then post your findings to the scientific community (the forum.) I'm eager to learn what happens!
You asked about the CO2 sensor in our current project. It is from a Swedish company, www.senseair.se/. You will see that they specialize in HVAC controls in nice packages with displays, but they also advertise OEM components. (HVAC=heating ventilating and air conditioning; OEM=original equipment manufacturer). I had the CO2 engine K30. I did not purchase it myself, but my understanding was that it cost a couple hundred dollars, well above your budget, and also that the company is not interested in supplying these to experimenters (They are looking for the OEMs, but you can always try!). I sorry I can't tell you about the actual project I was working on and its intent, because I was doing it under contract for a customer.
You will find that "raw" sensors are often much cheaper than "finished" sensors that are mounted on a circuit board with substantial circuitry. That is because raw sensors often have shortcomings or at least side effects that need to be accounted for. It is not that the final circuit is that expensive to produce, but there is an investment in engineering and scientific insight that go into the design, and there may be substantial production costs for special parts and packaging and, not the least, calibration. The art takes leaps when people figure out how to do these things more accurately and at the same time cheaply. There is a cutting edge in terms of accuracy that is expensive, but as in many fields, what was $2000 a few years ago can now be had for $200 and raw sensors for less.
Mark in NH said...
Where exactly in the program does your 'restart' subroutine go? Does it replace any command lines, or is it in addtion to what's already there?
Do the four lines (below) that you suggested we change in the initialization sequence replace line commands that are already there?
The code I showed goes at the very beginning of the program. It isn't
a subroutine. It replaces what you initially had.
Likewise for the four lines of my code that perform the initialization of
the Vinculum. The important line is the PAUSE 500 statement. That one
will take care of any switch bounce you may have when the parachute
opens and the battery is switched on.
Have you analyzed how long your bot will run on the 9v battery? Is that in fact your intended power supply for the launch?
You had asked,
>Would the commands (?) below do exactly the same thing, or are certain words ('i', for >example) 'reserved'?
>fish VAR byte
>fish = 0
>FOR fish = 0 to 120
>Is this any different? If so, how, and why?
>counter VAR byte
>counter = 0
>FOR counter = 0 to 120
Those two sequences are the in fact the same, and they do in fact associate a certain 8 bit byte location in the Stamp memory with that name. And then assign a value of zero. And then step through a sequence of values from 0 to 120. The statement, fish=0, is superfluous, because the next statement, FOR fish=0 TO 120, in and of itself starts by assigning the value 0 to that variable. Usually the program will step through all 121 values of the variable (do you see why there are 121 and not 120?) But the program might play with the value of fish or counter within the FOR-NEXT loop and cause it to terminate early or (maybe inadvertently) cause it to loop forever. The point is that the loop counter is a variable like any other.
You aske about reserved words. Yes, there are certain words that you can find in an appendix at the end of the BASIC STAMP manual. For example, COUNT is a PBASIC command and could not be used as the variable, but "counter" or "icount" would be okay, as would simply "i".
I've added the changes into the program, but, I am receiving an error. It pops up a message saying, "Expected a label", then highlights "idx_1" in the program. What can I do to fix "idx_1" so the program can download and run?
Again, without seeing the program this is just an educated guess. You folks have been doing a fine job of warming up my crystal ball
My guess is that idx_1 should probably be defined as a BYTE, as follows:
idx_1 VAR BYTE
That will permit the variable to contain a range of values from 0 -> 255. If you need a larger range, then it must be defined as a WORD, in a similar manner as above.
Just as an aside, all of the team would benefit greatly from downloading (individually) the educational text "What's a Microcontroller". Many of these somewhat elementary concepts, as well as some more advanced ones are discussed therein. Here is a link to the PDF document which is the 7th item down from the top of that list: http://www.parallax.com/tabid/535/Default.aspx
Regards,
Bruce Bates
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Genius is one percent inspiration and ninety-nine percent perspiration."
·· Remember at practice yesterday when we redefined a 'Byte' (a 0 to 255 command) as a 'Word' command (holds more than 255) at the top of the program like this:
motorruntime····VAR··· Byte····
>···· motorruntime···· VAR··· Word
That's where and how you define idx_1 as a BYTE· as Mr. Bates suggested. Look at it again in the program we used yesterday and see where else 'motorruntime' is defined, and how.
idx_1··· VAR···BYTE
Let me compliment you·for remembering to thank our new friends for helping us our on the forum each time. You're getting a real and practical education from some real experts! Thanks too, for posting the robot pictures today. I think everyone found it helpful to see what it is they're actually helping to program. Let me know how the idx_1 VAR command works. I'm headed to the robot right now myself to try the debug!
Thanks,
I have defined "idx_1" as a variable now, and I am no longer getting a message about it. However, I am now getting the error message "Undefined symbol" when I tried to download the program to our robot. After the message, "Undefined symbol", it jumps to and highlights "T9600", in our program. What is T9600 and how to I fix it so I can get the program to run? I have also attached the version of the program I am using.
SEROUT TX\CTS, T9600, [noparse][[/noparse]"E", CR] ' Sync Command Character
to
SEROUT TX\CTS, Baud, [noparse][[/noparse]"E", CR] ' Sync Command Character
My original program had the following at the beginning of the constant
definitions:
#SELECT $STAMP
#CASE BS2, BS2E, BS2PE
T1200 CON 813
T2400 CON 396
T4800 CON 188
T9600 CON 84
T19K2 CON 32
T38K4 CON 6
#CASE BS2SX, BS2P
T1200 CON 2063
T2400 CON 1021
T4800 CON 500
T9600 CON 240
T19K2 CON 110
T38K4 CON 45
#CASE BS2PX
T1200 CON 3313
T2400 CON 1646
T4800 CON 813
T9600 CON 396
T19K2 CON 188
T38K4 CON 84
#ENDSELECT
This group of statements let the code be compiled correctly for
any flavor of Stamp that was used. The Stamp directive controls
how the constant T9600 is defined.
···Can we simply change 'T9600' to 'Baud' since 'Baud' is a program command we already use in our program as below...?
Baud·······CON······ 84············· ' Serial Baud Rate 9600 bps (BS2)
I'm stumped at this point. After·defining 'idx_1'· as a VAR· Byte, we now get an error message at 'Found_E'. After three hours of re-entering code, trial-and-error experimentation, head-scratching (and head-banging!), I surrender for now. Score at halftime: Computer 3, M. Kibler 1...
The program gets hung up 'initializing' directly from the robot somewhere along about here, seemingly at the DEBUG "...." line below:
DEBUG "3) DataLogger Initialization -->"
Check_Drive:
DO ··· SEROUT TX\CTS, Baud, [noparse][[/noparse]CR] ··· GOSUB Get_Data ··· IF buffer(0) = ">" THEN ····· EXIT ··· ELSEIF buffer(0) = "N" AND buffer(1) = "D" THEN ····· DEBUG "." ··· ELSEIF buffer(0) = "D" AND buffer(1) = "D" AND flag = 0 THEN ·····DEBUG "Connected!", CR, "Accessing..." ····· flag = 1 ··· ELSE ·····DEBUG "...." ··· ENDIF ··· PAUSE 1 · LOOP · DEBUG " *INITIALIZED*", CR, CR
I'm open to ideas, guys... See you after 'halftime'. 'Programmers' will make a second half comeback vs. Computers!
Mark
Andrew - Be sure to change the two PAUSE commands at the start of the program·to 500 (as suggested previously - see program below). I tried it, and now the Datalogger initializes directly from·the robot (after the program is downloaded to to the robot.) That's progress. But that's all the further I got this evening.
'
[noparse][[/noparse] Initialization ]
PAUSE·500····························· ' 1000 = 1 second. 500 allows 1/2 second to settle
HIGH TX································' Initialize Transmit Line
LOW RTS································ ' Take Vinculum Out Of Reset
PAUSE 500······························ ' Allow 1/2 Second To Settle
I'm still·puzzled·about how to get the Datalogger to record data by running the·program directly from the robot. I worked at·it for the last three hours··· and all I got done was making it initialize (by changing the PAUSE statement to 500). I'm stumped. Stick with it, Andrew. You're doing good work! We'll get there; we'll figure it out.
Changing T9600 (9600 TRUE) to 84 (9600 TRUE) is fine. T9600 is just a constant that should be equal to 84 in the data definitions [noparse][[/noparse]T9600 CON 84]. It's generally considered easier to remember T9600 than it is to remember the numeric value 84, but use whichever one is easier for you. The program doesn't know the difference during execution.
I can't help you much with the error message at "Found_E" as I think it came from Phil Kenny's code. I'm sure he can tell you exactly what to do to fix the error, but since no copy of the present program was attached, I'm at a loss to do so <ahem>.
Speaking of PAUSEs (last post above), you may want to change the PAUSE 1 in the Check_Drive: routine to a PAUSE 250. This seems appropriate when your program is compared to the Parallax Demo program found on the Parallax web site with the Datalogger hardware.
Give these changes a shot, and let us know how you make out. We've GOT to improve these scores before the second half is over! No computer has beaten a decent programmer yet, and you folks are well on your way.
Regards,
Bruce Bates
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Genius is one percent inspiration and ninety-nine percent perspiration."
I've added the changes into the program, but, I am receiving "Undefined symbol", and it jumps to and highlights "iobyte". What can I do to fix this so I can download the program?
· Consider defining 'iobyte' as 'iobyte3', 'iobyte4', etc. at the top of our program (iobyte and iobyte1 are already defined, I believe.) When you redefine 'iobyte' as 'iobyte4', be sure to change it to 'iobyte4' everywhere in the program:
One can't just arbitrarily add, change, or modifiy variable names or size allocations, just to make errors disappear. It may appear to be an effective means to an end, but it will doubtless have a deleterious effect on·your program in the end analysis!
I have included·an entire routine below (more than is perhaps necessary) only for clarity. Within that routine you will see that I have changed the existing iobyte to iobyte1 which is what's needed by the Get_Data routine (which see). I have also added some white space (blank lines) to aid in the readability.
[noparse][[/noparse]code]
Restart:
DEBUG "Restart", CR
PAUSE 400······························ ' Allow Time To Settle
HIGH TX································ ' Initialize Transmit Line
LOW RTS································ ' Take Vinculum Out Of Reset
PAUSE 500······························ ' Allow Time To Settle
DEBUG "Done!", CR, "Synchronizing..."
idx_1 = 0······························· ' Initialize index to zero
DO
·· SEROUT TX\CTS, T9600, [noparse][[/noparse]"E", CR]······· ' Sync Command Character ·· GOSUB Get_Data······················· ' Get Response ·· PAUSE 450
·· idx_1 = idx_1 + 1·················· ' Increment index
·· IF iobyte1 = $0d THEN GOTO Found_E ·· IF idx_1+1 > 5··· THEN GOTO Restart
LOOP UNTIL ioByte1 = $0D················ ' Wait For Carriage Return
[noparse][[/noparse]/code]
While we're making changes, let's add a bit of professionalism to this program. It's really nothing more than some added documentation. However, it will aid in identifying certain aspects of the program such as when the original program was written and who wrote it, who last made changes, when the changes were made, etc. Here is what I would sugggest as a starter, but feel free to change it as you like, since it's nothing more than comments.
' {$STAMP BS2}
' {$PBASIC 2.5}
'
' Program Name: Humidity Data Acquisition and Robot Movement Program
' Original Program Written By: [noparse][[/noparse]Enter Name]
' Program Initially Written: xx/yy/zzzz
' Revision Date: 02/18/2008
' Last Revision Made By: [noparse][[/noparse]Enter Name]
Regards,
Bruce Bates
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Genius is one percent inspiration and ninety-nine percent perspiration."
I've made some changes to the program as you suggested and now I am receiving, "Undefined label", for "Found_E". What is "Found_E" and what do I 'define' it as?
Thanks for your help,
Andrew
[noparse][[/noparse]EDIT] I've attached the current version of the program if you want it·
Post Edited (Andrew Mahn) : 2/19/2008 7:45:32 PM GMT
Comments
Servo motors require that you send them a control pulse roughly 50 times a second or they shut themselves off until they get another control pulse (I think to save power in case they're out of range ... when they're used in a radio controlled vehicle). The PAUSE 20 provides the 20ms pause between pulses so you get roughly 50 per second. The PULSOUT statement actually sends the pulse whose width is determined by the 2nd number in the statement. The FOR/NEXT just provides the looping (for 121 times in this case).
Note: In a previous question, you had a FOR/NEXT and DO/LOOP combined. They have to be nested. You can't have them overlapped. In other words, FOR / DO / LOOP / NEXT is allowed and DO / FOR / NEXT / LOOP is allowed, but DO / FOR / LOOP / NEXT is forbidden.
·· Thanks for your post. It helps me understand better what's happen in the line commands so I can try and explain it to the team this afternoon.
So PAUSE can be used at least two ways then, yes?
1) As a true pause between FOR/NEXT (etc.) commands where 1000 =· second pause) as below
FOR motormovementtime = 0 TO 60
······ PULSOUT 15, 650
······ PULSOUT 13, 850
······ PAUSE 20
NEXT
PAUSE 500·· ' (500·means 500 ms, or 1/2 second)
FOR motormovementtime = 0 TO
·······PULSOUT 15, 650
······ PULSOUT 13, 850
······ PAUSE 20
NEXT
2) As a PAUSE between·pulses in a PULSOUT command (to motors, etc.)
FOR motormovementtime = 0 TO 60
······ PULSOUT 15, 650
······ PULSOUT 13, 850
······ PAUSE 20
NEXT
I now understand that DO/LOOP commands and FOR/NEXT commands have to be 'nested' (one inside the other.) Thanks! Let's say we want to loop a FOR/NEXT command then, to make the motors loop through a sequence twice (3 times,·4 times, etc.) What do we enter for the 'UNTIL' or 'WHILE' command value, and where, because the program·prompts us for it when we try to enter the subroutine below. Because the FOR/NEXT commands are 'nested' within the DO/LOOP command as you suggested, is it in the correct sequence below?
DO
·· FOR motormovementtime = 0 TO 120
····· ·PULSOUT 15, 650
······ PULSOUT 13, 850
······ PAUSE 20
···NEXT
LOOP ---> UNTIL?· --->·WHILE? (*assume we want the sequence above to loop three times)
7·degrees and sunny in NH,
Mark
In the case you mention, it's better to use two nested FOR / NEXT loops. You need another variable for the outer loop. The DO/WHILE/UNTIL loop is used for cases where the loop is conditional on something else like an I/O state ("IN1 == 0") or a complex relationship ("x < 5 and a <> 0"). In your case, you'd have:
·· The (attached) 'robot in rocket' program runs great. It records data, moves forward 1 meter, backs up 40 cm, turns 45 degrees, records data, and repeats the program again perfectly. Thanks everyone!
The robot is supposed to·turn on and run·when it's deployed form the rocket. Prior to flight we set the Parallax board switch to "2" and·then install it in the payload bay. We have a simple switch mechanism that turns power on when the robot comes out of the rocket. However, when we run the robot on the floor (by flipping·our switch "on" instead of attaching it directly to the computer using the serial cord), here's what happens:
1) Green Parallax power light comes on. A-OK
2) Red light on Parallax Datalogger light comes on. It does·NOT blink 'red-green-red-green'' but stays red. The light inside the flash drive does not turn on.
3) When we push the small black 'reboot' button on the Parallax board,·the Datalogger light stays red, the flash drive light blinks fast (indicating that it's initializing), then the Datalogger and flash drive blink back and forth red-green-red-green-red-green showing us that data is being acquired (the first program step.)
4) Next (last in the program sequence) the robot moves forward, backward, turns, then collects data all over again as it's supposed to.
Here's the glitch (and a big one!): we will not be a mile up in the air when·the robot·comes out of the rocket! Therefore, we cannot push the black reset button on the Parallax board to make the program run. I'm fairly certain there must be a program 'fix' (cycle the initialization sequence through twice, for example?) We just spent the better part of our pratice·today trying to 'fix' the program so·it·runs independently of direct connection to the computer (by reading the book, commenting out various·line commands, etc.) Unfortunately, we struck out.
Andrew Tim, and/or Tyler should be posting a similar note sometime soon. Any ideas how to remedy this by modifying the program? I'm stumped (but optomistic!)
Thanks,
Mark
·· We tried your idea of 'nesting' one FOR/NEXT command inside the other at today's practice to effectively loop a subroutine, and it worked marvelously! The kids had a great time trying it, then experimenting with nested FOR/NEXT commands inside of multiple FOR/NEXT commands, just to see what would happen. You're teaching some eager young minds excellent programming (and I wish I was as clever at this as everyone else is. I'm discovering that it WILL take time!) Thanks, Mike!
Mark
When you say "We have a simple switch mechanism that turns power on when the robot comes out of the rocket.", what are you actually doing?
Are you switching ON an external power supply which feeds a PCB on which the Stamp is mounted? (PCB = printed circuit board)
Are you switching ON a battery lead attached to a PCB on which the Stamp is mounted?
Are you using a Parallax Carrier Board which has a built-in power switch, and that's what's being switched ON?
Regards,
Bruce Bates
p.s. Did you receive the private message I sent to you?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Genius is one percent inspiration and ninety-nine percent perspiration."
Thomas Alva Edison
· We're switching ON an external power supply which feeds power to the a PCB (didn't know what that meant before..!) It's essentially a small headphone-type jack into which we insert a thin plastic dowel. This shuts off the power until the dowel is physically pulled out. When the robot ejects from the rocket, the plastic dowel is pulled out, turning power on. One of the parents wired it and I believe the wires from the servomotor lead into, and out of it. Andrew has the robot and he's an hour away.
ANDREW: Please check where this 'jack' is wired on the robot and post a reply to Mr. Bateas and I.
Bruce, I think·rearranging the·program sequence somehow might make it work. last night I ran a version of the program (motors on first, data collection next) and the motors came on instantly, the datalogger initialized, but data wasn't sent to the flash drive...
Should we post a picture of the 'bot here on the forum? Would that help?
I·have a roomful of energetic students right now but I will check in·throughout the day, as always.
Thanks·Bruce!
Mark
···Attached is·a photo and·a brief·explanation of the robot's 'power-on mechanism'. I'll post more details photos if folks would like, so you can see the 'switch' in more details. I think the glitch is in the initialization sequence, though, because when we run an earlier verison of the program, the motors run and the Datalogger initializes the flash drive (but records no data.)
Thanks,
Mark
I've looked how the "headphone-type jack" is wired into the robot. It is connected mid-way between the 6-9 VDC input and the 9v battery. I've also attached a few pictures of the robot, if you want them.
-Andrew
I've experienced a similar problem with my Datalogger.
Here is my solution:
Essentially it limits the number of passes thru the loop
looking for an 'E', then forces the Vinculum to go thru the Reset
sequence again.
This seems to work very reliably in my application.
I'd change the following lines in your initialization code:
You may have some contact bounce when the the pin is pulled that
connects the battery. The longer PAUSE of 500 may help if that is the case.
phil
Post Edited (phil kenny) : 2/18/2008 4:21:53 PM GMT
·· Thanks for the post! Did you see the photos of pur robot that Andrew posted (above)? Where exactly in the program does your 'restart' subroutine go? Does it replace any command lines, or is it in addtion to what's already there?
Do the four lines (below) that you suggested we change in the initialization sequence replace line commands that are already there? I don't have the program or the robot in front of me (but I can't wait to get home to try this.)
Thanks!
Mark
PAUSE·10································'·1000·=·1·second.·500·allows·1/2·second·to·settle
HIGH·TX·································'·Initialize·Transmit·Line
LOW·RTS·································'·Take·Vinculum·Out·Of·Reset
PAUSE·500······························'·Allow·1/2·Second·To·Settle
Andrew: Try·Mr. Kenny's suggested changes to the program, run the robot with the changes, then post your findings to the scientific community (the forum.) I'm eager to learn what happens!
Mr. Kibler
You asked about the CO2 sensor in our current project. It is from a Swedish company,
www.senseair.se/. You will see that they specialize in HVAC controls in nice packages with displays, but they also advertise OEM components. (HVAC=heating ventilating and air conditioning; OEM=original equipment manufacturer). I had the CO2 engine K30. I did not purchase it myself, but my understanding was that it cost a couple hundred dollars, well above your budget, and also that the company is not interested in supplying these to experimenters (They are looking for the OEMs, but you can always try!). I sorry I can't tell you about the actual project I was working on and its intent, because I was doing it under contract for a customer.
You will find that "raw" sensors are often much cheaper than "finished" sensors that are mounted on a circuit board with substantial circuitry. That is because raw sensors often have shortcomings or at least side effects that need to be accounted for. It is not that the final circuit is that expensive to produce, but there is an investment in engineering and scientific insight that go into the design, and there may be substantial production costs for special parts and packaging and, not the least, calibration. The art takes leaps when people figure out how to do these things more accurately and at the same time cheaply. There is a cutting edge in terms of accuracy that is expensive, but as in many fields, what was $2000 a few years ago can now be had for $200 and raw sensors for less.
I looked at the CO2 sensor from www.vernier.com/probes/co2-bta.html (educational sensors), and see that it is $250.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
The code I showed goes at the very beginning of the program. It isn't
a subroutine. It replaces what you initially had.
Likewise for the four lines of my code that perform the initialization of
the Vinculum. The important line is the PAUSE 500 statement. That one
will take care of any switch bounce you may have when the parachute
opens and the battery is switched on.
phil
Have you analyzed how long your bot will run on the 9v battery? Is that in fact your intended power supply for the launch?
You had asked,
>Would the commands (?) below do exactly the same thing, or are certain words ('i', for >example) 'reserved'?
>fish VAR byte
>fish = 0
>FOR fish = 0 to 120
>Is this any different? If so, how, and why?
>counter VAR byte
>counter = 0
>FOR counter = 0 to 120
Those two sequences are the in fact the same, and they do in fact associate a certain 8 bit byte location in the Stamp memory with that name. And then assign a value of zero. And then step through a sequence of values from 0 to 120. The statement, fish=0, is superfluous, because the next statement, FOR fish=0 TO 120, in and of itself starts by assigning the value 0 to that variable. Usually the program will step through all 121 values of the variable (do you see why there are 121 and not 120?) But the program might play with the value of fish or counter within the FOR-NEXT loop and cause it to terminate early or (maybe inadvertently) cause it to loop forever. The point is that the loop counter is a variable like any other.
You aske about reserved words. Yes, there are certain words that you can find in an appendix at the end of the BASIC STAMP manual. For example, COUNT is a PBASIC command and could not be used as the variable, but "counter" or "icount" would be okay, as would simply "i".
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
I've added the changes into the program, but, I am receiving an error. It pops up a message saying, "Expected a label", then highlights "idx_1" in the program. What can I do to fix "idx_1" so the program can download and run?
Thanks,
Andrew
It's a bit tough to tell without seeing the program, but let's give it a shot. Chances are better than even that one of two things happened:
You didn't define "idx_1"
You may have misspelled it "idx-1"
If this is not the case, please supply the recently altered program as an attachment to your next post.
Regards,
Bruce Bates
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Genius is one percent inspiration and ninety-nine percent perspiration."
Thomas Alva Edison
I don't believe "idx_1" is defined. Where (and what) would I define it as?
-Andrew
Again, without seeing the program this is just an educated guess. You folks have been doing a fine job of warming up my crystal ball
My guess is that idx_1 should probably be defined as a BYTE, as follows:
idx_1 VAR BYTE
That will permit the variable to contain a range of values from 0 -> 255. If you need a larger range, then it must be defined as a WORD, in a similar manner as above.
Just as an aside, all of the team would benefit greatly from downloading (individually) the educational text "What's a Microcontroller". Many of these somewhat elementary concepts, as well as some more advanced ones are discussed therein. Here is a link to the PDF document which is the 7th item down from the top of that list:
http://www.parallax.com/tabid/535/Default.aspx
Regards,
Bruce Bates
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Genius is one percent inspiration and ninety-nine percent perspiration."
Thomas Alva Edison
I would recommend adding the following to your variable declarations:
idx_1 VAR counter.LOWBYTE
This will make temporary use of the low byte in the variable, counter.
Since idx_1 is only used in one particular section of the code, this
is permissible.
Or you could change the name from idx_1 to counter throughout the
code without any ill effects.
If you haven't used aliasing to reuse variables with meaningful names,
here's an opportunity to learn about aliasing.
phil
·· Remember at practice yesterday when we redefined a 'Byte' (a 0 to 255 command) as a 'Word' command (holds more than 255) at the top of the program like this:
motorruntime····VAR··· Byte····
>···· motorruntime···· VAR··· Word
That's where and how you define idx_1 as a BYTE· as Mr. Bates suggested. Look at it again in the program we used yesterday and see where else 'motorruntime' is defined, and how.
idx_1··· VAR·· ·BYTE
Let me compliment you·for remembering to thank our new friends for helping us our on the forum each time. You're getting a real and practical education from some real experts! Thanks too, for posting the robot pictures today. I think everyone found it helpful to see what it is they're actually helping to program. Let me know how the idx_1 VAR command works. I'm headed to the robot right now myself to try the debug!
Thanks,
Mr. KIbler
·
I have defined "idx_1" as a variable now, and I am no longer getting a message about it. However, I am now getting the error message "Undefined symbol" when I tried to download the program to our robot. After the message, "Undefined symbol", it jumps to and highlights "T9600", in our program. What is T9600 and how to I fix it so I can get the program to run? I have also attached the version of the program I am using.
Thanks in advance,
Andrew
Change the following line of code
to
My original program had the following at the beginning of the constant
definitions:
This group of statements let the code be compiled correctly for
any flavor of Stamp that was used. The Stamp directive controls
how the constant T9600 is defined.
phil
···Can we simply change 'T9600' to 'Baud' since 'Baud' is a program command we already use in our program as below...?
Baud·······CON······ 84············· ' Serial Baud Rate 9600 bps (BS2)
I'm stumped at this point. After·defining 'idx_1'· as a VAR· Byte, we now get an error message at 'Found_E'. After three hours of re-entering code, trial-and-error experimentation, head-scratching (and head-banging!), I surrender for now. Score at halftime: Computer 3, M. Kibler 1...
The program gets hung up 'initializing' directly from the robot somewhere along about here, seemingly at the DEBUG "...." line below:
DEBUG "3) DataLogger Initialization -->"
Check_Drive:
DO
··· SEROUT TX\CTS, Baud, [noparse][[/noparse]CR]
··· GOSUB Get_Data
··· IF buffer(0) = ">" THEN
····· EXIT
··· ELSEIF buffer(0) = "N" AND buffer(1) = "D" THEN
····· DEBUG "."
··· ELSEIF buffer(0) = "D" AND buffer(1) = "D" AND flag = 0 THEN
··· ··DEBUG "Connected!", CR, "Accessing..."
····· flag = 1
··· ELSE
····· DEBUG "...."
··· ENDIF
··· PAUSE 1
· LOOP
· DEBUG " *INITIALIZED*", CR, CR
I'm open to ideas, guys... See you after 'halftime'. 'Programmers' will make a second half comeback vs. Computers!
Mark
·
Andrew - Be sure to change the two PAUSE commands at the start of the program·to 500 (as suggested previously - see program below). I tried it, and now the Datalogger initializes directly from·the robot (after the program is downloaded to to the robot.) That's progress. But that's all the further I got this evening.
'
[noparse][[/noparse] Initialization ]
PAUSE·500····························· ' 1000 = 1 second. 500 allows 1/2 second to settle
HIGH TX······· ·························' Initialize Transmit Line
LOW RTS································ ' Take Vinculum Out Of Reset
PAUSE 500······························ ' Allow 1/2 Second To Settle
I'm still·puzzled·about how to get the Datalogger to record data by running the·program directly from the robot. I worked at·it for the last three hours··· and all I got done was making it initialize (by changing the PAUSE statement to 500). I'm stumped. Stick with it, Andrew. You're doing good work! We'll get there; we'll figure it out.
Good evening,
Mr. Kibler··
Changing T9600 (9600 TRUE) to 84 (9600 TRUE) is fine. T9600 is just a constant that should be equal to 84 in the data definitions [noparse][[/noparse]T9600 CON 84]. It's generally considered easier to remember T9600 than it is to remember the numeric value 84, but use whichever one is easier for you. The program doesn't know the difference during execution.
I can't help you much with the error message at "Found_E" as I think it came from Phil Kenny's code. I'm sure he can tell you exactly what to do to fix the error, but since no copy of the present program was attached, I'm at a loss to do so <ahem>.
Speaking of PAUSEs (last post above), you may want to change the PAUSE 1 in the Check_Drive: routine to a PAUSE 250. This seems appropriate when your program is compared to the Parallax Demo program found on the Parallax web site with the Datalogger hardware.
Give these changes a shot, and let us know how you make out. We've GOT to improve these scores before the second half is over! No computer has beaten a decent programmer yet, and you folks are well on your way.
Regards,
Bruce Bates
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Genius is one percent inspiration and ninety-nine percent perspiration."
Thomas Alva Edison
I've added the changes into the program, but, I am receiving "Undefined symbol", and it jumps to and highlights "iobyte". What can I do to fix this so I can download the program?
Thanks,
Andrew
· Consider defining 'iobyte' as 'iobyte3', 'iobyte4', etc. at the top of our program (iobyte and iobyte1 are already defined, I believe.) When you redefine 'iobyte' as 'iobyte4', be sure to change it to 'iobyte4' everywhere in the program:
iobyte4··· VAR·· Byte·· (or Word)
Mr. Kibler
One can't just arbitrarily add, change, or modifiy variable names or size allocations, just to make errors disappear. It may appear to be an effective means to an end, but it will doubtless have a deleterious effect on·your program in the end analysis!
I have included·an entire routine below (more than is perhaps necessary) only for clarity. Within that routine you will see that I have changed the existing iobyte to iobyte1 which is what's needed by the Get_Data routine (which see). I have also added some white space (blank lines) to aid in the readability.
[noparse][[/noparse]code]
Restart:
DEBUG "Restart", CR
PAUSE 400······························ ' Allow Time To Settle
HIGH TX································ ' Initialize Transmit Line
LOW RTS································ ' Take Vinculum Out Of Reset
PAUSE 500······························ ' Allow Time To Settle
DEBUG "Done!", CR, "Synchronizing..."
idx_1 = 0······························· ' Initialize index to zero
DO
·· SEROUT TX\CTS, T9600, [noparse][[/noparse]"E", CR]······· ' Sync Command Character
·· GOSUB Get_Data······················· ' Get Response
·· PAUSE 450
·· idx_1 = idx_1 + 1·················· ' Increment index
·· IF iobyte1 = $0d THEN GOTO Found_E
·· IF idx_1+1 > 5··· THEN GOTO Restart
LOOP UNTIL ioByte1 = $0D················ ' Wait For Carriage Return
[noparse][[/noparse]/code]
While we're making changes, let's add a bit of professionalism to this program. It's really nothing more than some added documentation. However, it will aid in identifying certain aspects of the program such as when the original program was written and who wrote it, who last made changes, when the changes were made, etc. Here is what I would sugggest as a starter, but feel free to change it as you like, since it's nothing more than comments.
' {$STAMP BS2}
' {$PBASIC 2.5}
'
' Program Name: Humidity Data Acquisition and Robot Movement Program
' Original Program Written By: [noparse][[/noparse]Enter Name]
' Program Initially Written: xx/yy/zzzz
' Revision Date: 02/18/2008
' Last Revision Made By: [noparse][[/noparse]Enter Name]
Regards,
Bruce Bates
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"Genius is one percent inspiration and ninety-nine percent perspiration."
Thomas Alva Edison
I will try to fix the program and let you know how it works.
Andrew
I've made some changes to the program as you suggested and now I am receiving, "Undefined label", for "Found_E". What is "Found_E" and what do I 'define' it as?
Thanks for your help,
Andrew
[noparse][[/noparse]EDIT] I've attached the current version of the program if you want it·
Post Edited (Andrew Mahn) : 2/19/2008 7:45:32 PM GMT