NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.
Sensors, Actuators, and Robotics » robot with 2 Continuous rotation servos help
March 14, 2012 by lukel |
Hi, my name is Luke, and I need help on making a robot. I have 2 Parallax (futaba) continuous servos. I am trying to get them to work. I want to make a rover that avoids bumping into stuff. I am also trying to use the Parallax Ping ultrasonic sensor to avoid the stuff. |
---|---|
March 14, 2012 by lukel |
Here is my code so far
|
March 14, 2012 by pcbolt |
Hi lukel - A few things jump out. You have two "pwm_set()" functions that do exactly the same thing. I guess you plan on using a different port in the future for x and y directions (BTW the pwm_setx() function needs a closing brace). Inside the pwm_init() you use pwm_set() but only the x/y versions are defined (I guess you could use either one or both if you are using two axis). Last thing is inside main() you don't call pwm_init(). I'm guessing some of the end code got chopped off of your post so I'm sure you put in the closing brace of the while (1) loop and a "return 0" in there. |
March 14, 2012 by lukel |
Thanks pcbolt, I read something about using 2 servos with 1 Atmega168. It said to do this. |
March 14, 2012 by pcbolt |
Yep. That sounds right. Keep posting on your project...sounds really interesting. |
March 14, 2012 by lukel |
I am now stuck on using the ultrasonic sensor. I need to send a pulse to it 5 us long to send an ultrasonic chirp. Then time it from the pulse to when the chirp comes back. |
March 14, 2012 by pcbolt |
Luke - I'm sure the guys that post on here will have better suggestions than I will but the way I see it you'd want to have as good a timing resolution as possible. Not so much for the outgoing pulse but for timing the return. Since the oscillator operates at 14,745,600 Hz, the finest resolution would be about 68ns. Your outgoing pulse of 5us would then take about 74 clock "ticks" or cycles. I'd set up a "send_pulse()" function to initialize the MCU timer to trigger an interrupt when it reaches 74, set the pulse pin HI. Then just let the interrupt routine turn the pulse pin LO, turn off the interrupt, reset the timer to 0 and set a new "overflow" interrupt that just counts the number of times the tick count went past 255. Then you'd need a separate "pin change" interrupt to measure when the chirp came back, store the "overflow count", get the current timer value, combine them and you'd have your answer. I wouldn't mind getting into finer detail, but I'd hate to deprive you of the value of discovery. |
March 15, 2012 by lukel |
Does this look right? I just don't know how to reset the timer.
|
March 15, 2012 by lukel |
Speaking of servos, can you change the PWM MIN and PWM MAX to 0. Would it make the ranges infinite? |
March 15, 2012 by pcbolt |
Luke - I may have actually overcomplicated things a bit. I think it would be better just to keep the interrupt the way it is (triggering at 74 ticks) that way every interrupt would be done at 5 usec. You really don't need any better timing than that since the speed of sound in air is about 1000 ft/sec. 5 usec means 0.005' therefore not a problem. I would try something like this then:
Please note, I don't have my guides with me right now so I don't remember the actual name of the pin change interrupt or how to set it up. However, the NK keyboard tutorial and source code has all that in it. |
March 15, 2012 by pcbolt |
Luke - Big oops here. Inside the "send_pulse()" function place this at the end (at line 19):
This will reset the timer to 0. |
March 15, 2012 by lukel |
Thank you so much. So this gets the time. Would you know how to convert it into inches. I think this is the formula: time ** 178. How would you do that. |
March 15, 2012 by pcbolt |
Speed of sound is 1126 ft/sec in air so that would be about 94 in/sec. The time is actually round trip time so you'd divide the time by 2 then multiply times 94, or just take the time measured and multiply times 47. Since we're measuring the number of times 5 micro seconds elapse, the final formula would be:
(You may have to include math.h to do the floating point arithmetic). If you just want to set a distance limit on when to stop the robot, you could just pre-figure the pulse time and not have to worry about the math. |
March 15, 2012 by lukel |
Thanks. I tried to upload the code and it had a list of errors. 0 us.c: In function 'main': us.c:18: error: 'PC4' undeclared (first use in this function) us.c:18: error: (Each undeclared identifier is reported only once us.c:18: error: for each function it appears in.) us.c:37: warning: implicit declaration of function 'timer_init' us.c:37: error: expected ';' before '{' token us.c: In function 'SIG_OUTPUT_COMPARE0A': us.c:68: warning: 'PIN_CHANGE_INTERRUPT' appears to be a misspelled signal handl er us.c:68: error: static declaration of 'PIN_CHANGE_INTERRUPT' follows non-static declaration us.c:68: error: previous declaration of 'PIN_CHANGE_INTERRUPT' was here |
March 15, 2012 by lukel |
Here is my code.
|
March 15, 2012 by pcbolt |
I found the actual name of the pin change interrupt, so on line 68 above, change
to
Next you have to place all the function blocks above "int main(){". Also the global variables (the ones with "volatile" in front) should go above "main()" as well. Inside the "main()" program block, keep lines 18 thru 28 the way they are. Add timer_init(); and move "double pulse_distance;" to the next line, then the line after that will be sei(); It should look like this:
Now you can start your infinite "while(1)" loop. All you need here is:
You'll notice I added a call to a new function named "pin_init()". This will setup the interrupt for pin changes and it should look like:
That reminds me, you'll have to add "void" in front of the "start_pulse(){" and "timer_init(){". Then add "return" at the end of each of these functions. It also looks like you need a closing brace for the SIGNAL function. I think we'd need to change the port direction of PC4 after sending the pulse...but first things first. See if the code changes will compile. Fingers crossed of course. |
March 16, 2012 by lukel |
Is this how you do it?
|
March 16, 2012 by lukel |
It didn't work. here is the list of errors. us.c: In function 'timer_init': us.c:20: error: 'OCROA' undeclared (first use in this function) us.c:20: error: (Each undeclared identifier is reported only once us.c:20: error: for each function it appears in.) us.c:23: error: 'pulse_flag' undeclared (first use in this function) us.c:24: error: 'timing_flag' undeclared (first use in this function) us.c: In function 'send_pulse': us.c:30: error: 'pulse_flag' undeclared (first use in this function) us.c: At top level: us.c:35: warning: 'SIG_OUTPUT_COMPARE0A' appears to be a misspelled signal handl er us.c: In function 'SIG_OUTPUT_COMPARE0A': us.c:37: error: 'pulse_flag' undeclared (first use in this function) us.c:40: error: 'pulse_count' undeclared (first use in this function) us.c:44: error: 'timing_flag' undeclared (first use in this function) us.c:47: error: static declaration of 'vector_4' follows non-static declaratio n us.c:47: error: previous declaration of 'vector_4' was here us.c: In function '__vector_4': us.c:49: error: 'pulse_time' undeclared (first use in this function) us.c: In function 'SIG_OUTPUT_COMPARE0A': us.c:66: warning: 'main' is normally a non-static function us.c: In function 'main': us.c:86: warning: implicit declaration of function 'start_pulse' us.c:88: error: 'pulse_time' undeclared (first use in this function) us.c: In function 'SIG_OUTPUT_COMPARE0A': us.c:92: error: expected declaration or statement at end of input |
March 16, 2012 by pcbolt |
Ok. First you'll need to add:
After line 14. Then, the "SIG_OUTPUT_COMPARE0A" function needs a closing brace. After that you need to put "return;" on line 32 and after line 14. And anywhere there is OCROA replace with OCR0A (the second "O" is actually the number "0"). |
March 17, 2012 by lukel |
us.c:37: warning: 'SIG_OUTPUT_COMPARE0A' appears to be a misspelled signal handl er us.c: In function 'SIG_OUTPUT_COMPARE0A': us.c:48: error: static declaration of 'vector_4' follows non-static declaratio n us.c:48: error: previous declaration of 'vector_4' was here us.c: In function 'main': us.c:83: warning: implicit declaration of function 'pin_init' us.c:89: warning: implicit declaration of function 'start_pulse' |
March 17, 2012 by pcbolt |
Luke - You could try replacing:
With:
Did you add a closing brace at the end of that function (at line 46)? The closing brace that is there now closes the "else" block not the function (or ISR) block. |
March 18, 2012 by lukel |
It compiled and worked!:) For some reason it delayed 5 seconds to read. |
March 31, 2012 by Ralphxyz |
lukel, what does your final code look like and you should add this to the Nerdkit community Library Project. Ralph |
March 31, 2012 by lukel |
How do you post something on the library? |
March 31, 2012 by Ralphxyz |
It is basically the same as posting here in the forum, it even uses the stupid/limited Markdown language syntax. You first need to signin. If you start on the first (ugly) page and scroll down to the bottom and select edit in the lower right corner you will view the text/code behind the page. Then follow the links to the Projects section and look at the way other Projects are written up and just duplicate them with your code. Of course do not save any of the pages you view, well even if you did save them and didn't make any changes you would not break anything just change the attribute. It might be easier to work in an editor on your PC rather than working in the actual page on the web. So you can just do a copy paste. If you have questions or problems let me know at rhulslander gmail.com Ralph |
March 31, 2012 by lukel |
How do you make a code look like a code? |
April 01, 2012 by Ralphxyz |
Darn Humberto sent out instruction on specifically doing that, which I no longer have. You can always indent your code preceded by four spaces that is what the "Indent Selection as Code Block" button does here in the forum. The Library uses the exact same syntax, both use the Markdown engine. Also you can look at other pages to see how they did it. Ahhh followed my own advice:
This came from bretm's (whom I really miss) Nerdkit LCD Library page in the Code Library section! So you put 10 tildes (~) then . language name in this case c_avr you could also do ~~.python for python code I think there are more hopefully someone who actually knows what they are talking about will jump in. And then you close the block with ten tildes ~~. These are not indented! Again it might be easier to do this in a editor rather than on the web page, using copy paste. Ralph |
Please log in to post a reply.
Did you know that our customers love us? Learn more...
|