Permalink
Browse files

example_servo_sequence app: Initial commit.

  • Loading branch information...
1 parent 98b910a commit 4eb7b3cfb9183b0f2cb0d362e850e480961f5f7d @DavidEGrayson DavidEGrayson committed Oct 14, 2011
@@ -0,0 +1,39 @@
+/** This file contains "responsible" blocking functions.
+These functions may take may take an indefinitely long time to execute, but
+during that time they will call frequentTasks() in a loop so that the Wixel
+can maintain its various responsibilities. If we decide we like this pattern,
+then the functions in this file might eventually be moved into the
+appropriate Wixel libraries. */
+
+#include <cc2511_map.h>
+#include <wixel.h>
+#include <usb.h>
+#include <usb_com.h>
+#include <servo.h>
+
+#include "blocking.h"
+
+// This is a slightly inaccurate delay function.
+// It will delay by at LEAST the number of milliseconds specified.
+// It will delay by at MOST
+// milliseconds + 1 + (maximum time that frequentTasks() takes).
+void waitMs(uint32 milliseconds)
+{
+ uint32 start;
+
+ if (milliseconds == 0){ return; }
+
+ start = getMs();
+ while(getMs() - start <= milliseconds){ frequentTasks(); }
+}
+
+void servosWaitWhileMoving()
+{
+ while(servosMoving()){ frequentTasks(); }
+}
+
+uint8 usbComRxReceiveByteBlocking()
+{
+ while(usbComRxAvailable() == 0){ frequentTasks(); }
+ return usbComRxReceiveByte();
+}
@@ -0,0 +1,15 @@
+// These are "responsible" blocking functions defined in blocking.c,
+// which call frequentTasks() while they are blocking.
+
+#ifndef _BLOCKING_H
+#define _BLOCKING_H
+
+void frequentTasks(void);
+
+void waitMs(uint32 milliseconds);
+
+void servosWaitWhileMoving(void);
+
+uint8 usbComRxReceiveByteBlocking(void);
+
+#endif
@@ -0,0 +1,168 @@
+/** example_servo_sequence app:
+
+Demonstrates how to write blocking code on the Wixel by showing
+how to generate a timed sequence of movements.
+
+Pin P0_2 is configured as a the servo pulse output.
+
+Most of the functions in the Wixel SDK is non-blocking, which mean they return
+within a few tens of microseconds or less. For example, a non-blocking
+function that blinks an LED on and off would looks like this:
+
+ void updateRedLed()
+ {
+ LED_RED( (getMs() >> 9) & 1 );
+ }
+
+The equivalent blocking code would look like this:
+
+ void blinkRedLed()
+ {
+ while(1)
+ {
+ LED_RED(0);
+ waitMs(512);
+ LED_RED(1);
+ waitMs(512);
+ }
+ }
+
+Blocking code can be easier to write and easier to understand, especially if it
+is doing something complex.
+*/
+
+#include <cc2511_map.h>
+#include <servo.h>
+#include <wixel.h>
+#include <usb.h>
+#include <usb_com.h>
+
+#include "blocking.h"
+
+// Prototypes for the example loop functions defined below.
+void loop(void);
+void loop_sequence_triggered_by_usb(void);
+void loop_sequence_triggered_by_digital_input(void);
+
+// Here we define what pins we will be using for servos. Our choice is
+// to just use one pin, P0_2, and designate it as servo 0.
+// The servo library supports up to 6 servos.
+uint8 CODE pins[] = {2};
+
+// This function gets called frequently and takes care of any tasks that need
+// to get done regularly, such as maintaining the Wixel's USB connection.
+// All blocking functions call frequentTasks while they are blocking.
+// There should be no blocking functions called from fequentTasks.
+void frequentTasks()
+{
+ boardService();
+ usbComService();
+ usbShowStatusWithGreenLed();
+}
+
+/** This function is called when the Wixel starts up. */
+void main()
+{
+ systemInit();
+ usbInit();
+ servosStart((uint8 XDATA *)pins, sizeof(pins));
+
+ while(1)
+ {
+ frequentTasks();
+ loop();
+ }
+}
+
+/** Performs a simple sequence of servo movements.
+ This is called in a loop, so the sequence will repeat indefinitely.
+
+ Some special blocking functions used here are defined in blocking.c.
+ The other functions are from the Wixel libraries and they are documented here:
+ http://pololu.github.com/wixel-sdk/
+ */
+void loop()
+{
+ servoSetSpeed(0, 130); // Set the speed of servo 0.
+ servoSetTarget(0, 1000); // Send servo 0 to position 1000 us.
+
+ servosWaitWhileMoving(); // Wait for it to get there.
+
+ LED_YELLOW(1);
+ waitMs(2000); // Wait 2 more seconds, with the yellow LED on.
+
+ LED_YELLOW(0);
+ servoSetTarget(0, 2000);
+ servosWaitWhileMoving();
+
+ servoSetTarget(0, 1500);
+ servosWaitWhileMoving();
+
+ servoSetTarget(0, 2000);
+ servosWaitWhileMoving();
+}
+
+/** Other example loop functions **********************************************/
+/** These other example loop functions below are provided to demonstrate more
+ * things that the Wixel is capable of.
+ * To use one of them, find the line above that says "loop();" and replace
+ * "loop" with the name of the loop function below that you want to call.
+ */
+
+/** Waits for a character to be sent from USB and then triggers a sequence of
+ * servo movements depending on what character was received. */
+void loop_sequence_triggered_by_usb()
+{
+ servoSetSpeed(0, 458);
+ servoSetTarget(0, 1500);
+
+ switch(usbComRxReceiveByteBlocking())
+ {
+ case 'a':
+ // An 'a' character was received on the USB virtual COM port. Perform sequence a.
+ servoSetTarget(0, 2000);
+ servosWaitWhileMoving();
+ waitMs(1000);
+ break;
+
+ case 'b':
+ // A 'b' character was received on the USB virtual COM port. Perform sequence b.
+ servoSetTarget(0, 1000);
+ servosWaitWhileMoving();
+ waitMs(1000);
+ break;
+
+ default:
+ // An invalid character was received, so blink the red LED.
+ LED_RED(1);
+ waitMs(20);
+ LED_RED(0);
+ break;
+ }
+}
+
+/** Waits for the voltage on pin P0_0 to go low, and then triggers a sequence of
+ * servo movements.
+ * By default P0_0 is configured as an input with a pull-up resistor.
+ * If you connect a normally-open button between P0_0 and one of the GND pins,
+ * then you can trigger the sequence of servo movements by pressing the button.
+ * */
+void loop_sequence_triggered_by_digital_input()
+{
+ servoSetSpeed(0, 458);
+ servoSetTarget(0, 1500);
+
+ if (!isPinHigh(0)) // Measure voltage on P0_0
+ {
+ LED_YELLOW(1);
+ servoSetTarget(0, 2000);
+ servosWaitWhileMoving();
+
+ waitMs(1000);
+
+ servoSetTarget(0, 1500);
+ servosWaitWhileMoving();
+
+ LED_YELLOW(0);
+ }
+}
@@ -0,0 +1 @@
+APP_LIBS := wixel.lib dma.lib servo.lib usb_cdc_acm.lib usb.lib gpio.lib
@@ -1,3 +1,13 @@
+/** test_servos app:
+ *
+ * This app tests the servo library by using it to transmit servo pulses on
+ * all six available pins: P0_2, P0_3, P0_4, P1_2, P1_1, and P1_0.
+ *
+ * This is mainly intended for people who are changing the servo library. If
+ * you just want to use the library to control a servo from a Wixel, see the
+ * example_servo_sequence app.
+ */
+
#include <cc2511_map.h>
#include <servo.h>
#include <wixel.h>
@@ -25,7 +25,7 @@
* The allowed pulse widths range from one 24th of a microsecond to 2500
* microseconds, and the resolution available is one 24th of a microsecond.
*
- * For example code that uses this library, please see the <code>test_servos</code>
+ * For example code that uses this library, please see the <code>example_servo_sequence</code>
* app in the Wixel SDK's <code>apps</code> directory.
*
* \section wiring Wiring servos

0 comments on commit 4eb7b3c

Please sign in to comment.