Servo Blind Automation with MSP430 January 16, 2012 at 2:17 AM

A while ago I modified a little 8-gram servo I had lying around for constant rotation and attached it to the blade pitch adjust(is thats what you call it!? 😕 ) mechanism in my blinds.  I’ve been meaning to build a simple controller for it for ages, so the other night I grabbed my MSP430 launchpad and some G2001 chips I had lying around. This was the result:

The servo is powered of the 5v from the usb port which seems to run it just fine, and the servo control pin is connected to P1.0 on the device.

This little G2001 only has 0.5kb or 512 BYTES!! of memory, So I stated off with a very minimal program just to get the servo spinning in each direction at the push of a button. After I had decided it was possible to do it with the limited code-space available I set about adding an interrupt vector that fires when the button is pressed and then spends the next second or so spinning the blind in the opposite direction to the previous press.(The fact I do all the heavy lifting from within the interrupt means I dont need to worry about switch de-bounce issues 😀 ) Once the code returns to the main loop, the device goes into the lowest power mode possible using almost no energy! 😀 I managed to get the final compiled codesize down to 378 Bytes! (I was proud of myself 8) )

I may still try add some functionality to the code, perhaps switch to a bigger processor and use the capacitive touch booster pack to make the blinds adjustable. I also plan on adding a mosfet to the servo that disconnects it from the supply when the processor is sleeping for even better efficiency. 😀

 

Here’s the code:
/*
* main.c - Servo Blind Controller
* - Robthepyro www.rambo.co.za
* - January 2012
*
* Connect the servo control pin ot port P1.0, Servo needs to be modified for continual rotation
* pushing the button on the launchpad connected to P1.3 alternatively opens and closes the blinds
*/

#include “msp430g2001.h”
#include “stdbool.h”

#define BTN BIT3
#define ServoPin 10

// Random defines
#define HIGH 1
#define LOW 0
#define OUTPUT 1
#define INPUT 0

// Arduino-ish functions
#define mSdelay(milliseconds) for(int x=0;x #define pinMode(pin, mode) {if(mode){P1DIR|=(1< #define digitalWrite(pin, mode) {if(mode){P1OUT |= (1< #define digitalRead(pin) (P1IN & pinBit(pin) ? HIGH : LOW)

const unsigned int moveTime = 100; // defines how much time the servo spends moving
unsigned char i; // used for loops
bool f = false; // determines the open or closed state of the blinds

void open(){ //opens the blinds, ~0.5ms pulses on servo every ~10ms
for(i = 0; i < moveTime; i++){
digitalWrite(ServoPin, HIGH);
__delay_cycles (600);
digitalWrite(ServoPin, LOW);
__delay_cycles (10000);
}
}

void close(){ // closes blinds, ~2.5ms pulses on servo every ~10ms
for(i = 0; i < moveTime; i++){ digitalWrite(ServoPin, HIGH); __delay_cycles (2600); digitalWrite(ServoPin, LOW); __delay_cycles (10000); } } #pragma vector = PORT1_VECTOR // interupt for button __interrupt void P1_ISR(void) { switch(P1IFG&BTN) { case BIT3:// if button is pressed if(f) { close(); f = false; } else { open(); f = true; } P1IFG &= ~BTN; // clear the interrupt flag return; default: P1IFG = 0; // probably unnecessary, but if another flag occurs // in P1, this will clear it. No error handling is // provided this way, though. return; } } // P1_ISR void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P1DIR |= (BIT0); // servopin output P1DIR &= ~BIT3; // switch input P1OUT |= BIT6; P1OUT &= ~BIT0; P1IES |= BIT3; // high -> low is selected with IES.x = 1.
P1IFG &= ~BIT3; // To prevent an immediate interrupt, clear the flag for
// P1.3 before enabling the interrupt.
P1IE |= BIT3; // Enable interrupts for P1.3
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ;

_BIS_SR(LPM4_bits + GIE);// enable interupts and go into lowest power mode

while(1)
{
// do nothing. cpu shut down
}

}

 

11 Responses to “Servo Blind Automation with MSP430”

  1. Hello, I am interested in your project and also try to make it for me with msp430g2231.
    However, your code was not posted.
    If you don’t mind, could you send me the code for me.
    Thank you

  2. Hi there Changha!
    I’ll review it tommorrow and see if I can get it to work on a g2231 quick, then post it here 🙂

  3. Thank you so much..~~

  4. Ok I made the required edits to the source file and uploaded it here for you. Should work on your G2231. try it out and let me know! post a vid even 🙂

  5. Thank you.
    It really works for me with my servo motor.
    It’s awesome.

  6. Great! make a video or something and I’ll put it up here 😀

  7. For god’s sake…

    http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&sqi=2&ved=0CEQQtwIwAA&url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DBt9zSfinwFA&ei=ECwxUPudKcei2wWr7oCYDQ&usg=AFQjCNG74QhIWItZQCl8BJ_IPh26S59nTg&sig2=fgOELVxPZVGBv_Z6e4G3qg

  8. Add an rtc and give it time of day control

  9. hi i used your code to run servo motor using G2231 ,the problem motor is rotating only upto 5-10 degrees and rotaing backwards.can u plz help me to rotate motor 90 degrees.
    [email protected]

  10. Good simple stuff.. but regarding using a Mosfet to disconnect the servo from the MCU. Could you not just tri-state the pin to disconnect it? Just a thought.

  11. @cde, watch this space, more advanced version in the works 😉 this was just to prove a point of using <0.5kb program space

    @gautam, what sort of servo motor are you using? do you have an oscilloscope?

    @Balu, Since the servo has it's own power and ground lines, it is always drawing current (technically it goes to sleep after a while but it will still draw a little bit of current) thus by having a mosfet to control the power to the servo, we can get power consumption really low 🙂

Leave a Reply