Question about Loop in SimpleIDE
NWCCTV
Posts: 3,629
Not sure what I did wrong with this code. It works the first time but after I press 2 to stop the Servo, pressing 1 will not start it again. I know it is something simple but just not sure what.
/*Test SIRC Remote.c Connect 38 kHz IR receiver to Propeller P10 Decodes button presses on Sony-compatible IR remote Run with Terminal */ #include "simpletools.h" // Libraries included #include "sirc.h" #include "servo.h" int main() // main function { sirc_setTimeout(1000); // -1 if no remote code in 1 s while(1) // Repeat indefinitely { // decoding signal from P10 print("%c remote button = %d%c", // Display button # decoded HOME, sirc_button(10), CLREOL); // from signal on P10 int button = sirc_button(10); if(button == 1)servo_speed(18,100); // P16 servo to 0 degrees if(button == 2)servo_stop(); pause(100); // 1/10 s before loop repeat } }
Comments
This needs a fix in the library, e.g. lockclr before lockret or graceful exit of the handler code. The latter may inflict some delay (stop would only set a flag) so may not be desirable.
I'll try to get an updated library posted here before the end of the day. If you are interested in adjusting the library yourself, try these tutorials first: http://learn.parallax.com/propeller-c-library-studies Note: Some of the memory saving lessons are no longer as significant, but it's still a good look into creating and editing libraries. After that, the servo library project is ...Documents\SimpleIDE\Learn\Simple Libraries\Motor\libservo\libservo.side. From what I gather from post #2 (thank you Kuroneko!) the servo_stop function needs a lockclr before the lockret. it would probably also be useful to add functions to stop sending signals to one or more selected servos so that you can allow servos to relax without stopping the entire driver.
Andy
Also, I noticed that the servo_start function gets a lock (potentially destroying/leaking an existing one) then calls servo_stop which - if the handler is running - frees it again. NG. Maybe servo_start shouldn't necessarily be public?
I do not yet have a library for you to test, but in the meantime, here is an undocumented servo library feature for you to try.
You can make the servo library selectively release control of a servo with servo_set(pin, 0). This function call just makes the library stop sending control signals to the servo, but the library itself keeps going, and it'll also continue to control other servos. Although I could document this, it seems like it would be better to have a function named servo_sleep(int pin) that calls servo_set(pin, 0). That way, folks can see in the library docs that servo_sleep allows the application to selectively release control of a servo connected to a particular I/O pin.
At any rate, here some code for you to test. It uses servo_set(18, 0) approach to release control of the servo. If you call servo_speed later (by pressing 1 on your remote), it should resume sending the control signals to that servo, and it'll start turning again. I also changed the remote delay to 200 ms. You could try 100, but much less than that might lead to missed remote button presses and it's also possible to send data to SimpleIDE Terminal more quickly than it can display.
Another approach would be to call servo_speed(pin, 0). Unlike servo_set(pin, 0), which just stops sending control signals to servo, servo_speed(pin, 0) would send the servo a "stay still" signal to a continuous rotation servo. Assuming you use that same command center the continuous rotation servo, it should stay still. This will cause a continuous rotation servo to exert a little more force to try to keep the servo in a given position than if the control signal disappeared altogether. It does take a little more current though, and if the servo falls out of calibration, you may notice it turning slowly.
Andy
Okay, clearing the lock after checking it out sounds good.
Yes, excellent point. I'll make it private.
Thanks again, Andy
EDIT: The thing I do not get is why after about 20 seconds or so the program no longer functions and I have to resend it. This is after stopping and starting the servo. How is a bot suppose to roam if the program stops every 20 to 30 seconds?
Here is an example of code driving a second servo. The library can run up to 14 servos in a single cog, so every time you servo_speed, servo_angle or servo_set with a new pin, the library puts that info in another memory slot, and the code running in another cog that sends servo pulses notices it within 1/50 of a second, and starts sending pulses to the new servo along with all the others.
1) Keep in mind that the sirc_button function returns -1 if no button is pressed before it times out. In that case, you could forget about the else, and go back to all if statements: if(button == 16)...if(button == 17)...if(button == -1)... You'd then put your stay still code in the if(button == -1) code block.
2) Set it up with if(...)...else if(...)...else if(...)...else... In your case, it would be if(button == 16)...else if(button == 17)...else... Your else condition would have the stay still code. It looks like you were trying to do this, but maybe missed changing if(button == 17) to else if(button == 17).
If you think about your code as it is, the problem occurs if you hold anything other than 17. If you hold 16, it briefly tells the robot to go forward, but then it gets immediately overridden by the if(button==17)...else... That else says, if it's anything other than 17, make it stay still. Well, if you are holding 16, that's not 17, so it stays still. So again, you can fix that by changing if(button == 17) to else if(button == 17). Then, your code will say if button is 16, go forward, else if button is 17, go backwards, else stay still.