This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Request to Check Code for Solenod Operated Clock

Other Parts Discussed in Thread: MSP430G2211, MSP430G2452, MSP430G2553

I have modified and revised the following code which passes through the build tool check without any errors and seems, to my logic, to be correct. I have added notes to the top of the code to explain what it is designed to achieve. I would be grateful if anyone could have a look through it and let me know whether I have made any glaring or silly errors anywhere that will prevent it from operating.

Thank you.

James.

/*
* Driver Code for Solenoid-operated Clock Counting Seconds and Minutes
*
* The clock will have two solenoids: one operating every second, the other each minute.
* The "seconds" solenoid needs to operate at full power each time.
* The "minutes" solenoid needs to increase its power gradually.
* The basic operation is by counting the Watchdog "ticks".
* The "seconds" solenoid has a variable that is made active each second, operates the solenoid and then resets.
* The "minutes" solenoid is operated once the seconds count reaches a minute's worth, when it is reset.
* Each coil is connected to a different output pin. The minute coil is on pin 4 and the seconds coil on pin 6.
*/
/*
* ======== Standard MSP430 includes ========
*/
#include <msp430.h>
/*
* ======== Grace related includes ========
*/
#include <ti/mcu/msp430/csl/CSL.h>
/*
* ======== Definitions and variables ========
*/
#define RedLED (BIT0) // Red LED on the LaunchPad (LEDs used during debug)
#define GreenLED (BIT6) // Green LED on the LaunchPad
#define Minute_Coil (BIT2) // Port 1 Bit 2 is high-active to the base of an NPN coil driver transistor
#define Seconds_Coil (BIT4) // Port 1 Bit 2 is high-active to the base of an NPN coil driver transistor
#define TestMode (BIT3) // Jumper to ground puts the circuit into Test Mode
// Test Mode runs the coil at a faster than normal rate to check out a newly-built clock
#define WDticksPerSecond 64 // Number of Watchdog Timer ticks (interrupts) per second
// The coil is initially turned on at partial power, then power is increased in increments every 15.2 mS to 100% power.
// Total on time is 155 mS and average power is 85%.
#define PWM_bump 25 // incremental PWM value (2.5%)
#define PWM_init 700 // initial PWM value (70% power)
#define PWM_full 1000 // full power PWM value 100%
unsigned int WDTticks = 0; // count of Watchdog Timer (interval timer) interrupt service calls
unsigned int seconds = 0; // elapsed seconds counted from WDTticks
unsigned int PWM; // percent of time to turn on the coil. 1000 = 100%.
unsigned int Finger_Tapper = 0; // VARIABLE TO CONTROL THE SECOND COIL

/*
* ======== Interrupt handlers ========
*/
/*
* Watchdog Timer Interrupt handler
*
* The microcontroller is awakened from low-power mode by the Watchdog Timer.
* The Watchdog Timer is set to interrupt every 15.2 mS or 64 times per second.
* Each interrupt or "tick" of the timer is counted, and after 64 ticks the seconds counter is incremented. This is the basic
* time-keeping function of the clock.
*
* The coil is turned on once per minute in normal mode and once per second in test mode.
* Test mode is set by installing a jumper connected to a port pin.
*
* The coil is turned on and off by enabling or disabling the bit in the Port Selection Register which connects the Timer A2 PWM
* output to the port.
* When disabled, the port pin is connected to the Port Output which is always set low (inactive) and the transistor is turned
* off.
* When enabled, the Timer A2 PWM output is connected to the port pin and the transistor turned on at the PWM duty cycle rate.
* Also when enabled, at each tick of the Watchdog Timer, or every 15.2 mS, the PWM percentage is increased a small amount.
* The current into the coil is thus gradually ramped up from partial to full power (100% duty cycle). This ramp up causes the
* solenoid plunger to activate more slowly and help prevent the clock's pawls from skipping a tooth on the ratchet wheel.
* The pawl would operate even more smoothly ramping up from 0%, but that would take more current and shorter battery life. The
* design choice is a trade-off between smoothness and battery life.
*
*
*/
void WDTISRHandler(void)
{
// If the Port Selection Register bit is active, the Timer A2 PWM output is connected to the port pin and the coil
//is on.
if (P1SEL & Minute_Coil) // is the coil on or off?
{
// The coil is on - ramp up the PWM percentage at each Watchdog Timer tick
CCR1 += PWM_bump; //increase the PWM percent a modest amount
if (CCR1 >= PWM_full) // are we at full power?
{
P1SEL &= ~Minute_Coil; // yes, turn off the coil
}
}
WDTticks++; // count the number of Watchdog Timer ticks to keep basic time
if (WDTticks >= WDticksPerSecond)
{
seconds++; // count seconds


// Once per second. This sets Finger_Tapper to activates a solenoid to count the seconds
    if (WDTticks >= WDticksPerSecond)
    {
    	Finger_Tapper = 1;
	if (Finger_Tapper == 1)
	{
    	CCR1 = PWM_full;// set the PWM to full value
        P1SEL |= Seconds_Coil; // turn the second coil on
	}
    	Finger_Tapper = 0;    	//Reset Finger_Tapper
    	P1SEL &= ~ Seconds_Coil; // turn the second coil off
	}


// once per minute in Normal mode, once per second in Test mode
if ((seconds >= 60) | (((P1IN & TestMode) == 0) & (seconds)) )
{
seconds = 0; // reset the seconds count
CCR1 = PWM_init; // set the PWM to initial value
P1SEL |= Minute_Coil; // turn the coil on
}
WDTticks = 0; // reset the Watchdog Timer ticks counter
}
}
/*
* ======== main ========
*/
int main(int argc, char *argv[])
{
CSL_init(); // Activate Grace-generated configuration
_BIS_SR(LPM0_bits); // Enter Low-power mode and wait for interrupts
return (0);
}

  • Hello James,

    Always mention the specific device you are using as this helps us understand which peripherals are available. You should also specify what part of the code you are most unsure about so that more specific advice can be provided. You did not attach your peripheral initialization so you must not be worried about how the WDT is set up, using the WDT to count time is unusual as compared to a timer or RTC but it can still get the job done.

    A few possible errors I notice is that you have a nested condition that is the exact same as the initial condition (WDTticks >= WDticksPerSecond) and that Finger_Tapper will always be set to 1 and never reset properly. It seems you may not be closing your if statements at the correct time, especially for single-command statements. Feel free to post more information once you have tried running the code and get unexpected operation, but always try stepping through the code with your debugger beforehand to get clues as to why the code is not working.

    Regards,
    Ryan
  • Ryan,


    Thank you for the feedback.

    I thought that I had mentioned the processor in question, but clearly forgot: it is a MSP430G2211. I copied the peripheral initialization from the original source for the code, so am cautiously optimistic that I have it right.

    My main reason for using the watchdog timer and this processor is that I thought that it would be easier to modify an existing programme, rather than start from scratch, especially as I know next to nothing about programming in C or processors. I actually have a MSP430G2452 and a MSP430G2553 that came with the LaunchPAd, but currently I lack the knowledge to set them up properly.

    I have a choice, really, it seems: either buy a MSP430G2211 so that I can run the code properly for debugging or learn enough to rewrite the code using a more conventional timer and one of my existing chips.

    UPDATE -  MSP430G2211 now ordered.


    I shall mull over my options.

    Regards,

    James.

  • James,

    The choice is most definitely yours to make. There are several online code examples and community projects for creating reliable timers using the MSP430 devices included with the MSP-EXP430G2 LaunchPad and porting the current project to these devices would take only a little time and effort. Plus you would learn more about C programming & MSP430 devices :) but if you've already ordered the MSP430G2211 then there's no harm in waiting for it to arrive.

    Best of luck,
    Ryan
  • Ryan,


    I shall persevere with my current route for now, as I have started and would like the satisfaction of completing it successfully. However, if I fail, or after I have completed the project for which I am trying to make this device, I shall look into learning more about the C and these devices in detail.

    Thank you for your help so far.

    Regards,

    James.

**Attention** This is a public forum