Tuesday, February 26, 2013

Good News, Not so Good News

Good news first.  I will be presenting a clinic on The LanuchPad for Model Railroading at the Streetsville Junction NMRA Convention in Mississauga, Ontario, Canada April 26th and 27thI am scheduled to present Friday evening and Saturday morning.  In the 1 hour presentation I will attempt to outline the whys and the hows of using LaunchPads as part of your model railroad empire. If all goes well, I will have a traveling display of LaunchPads animating things like crossing flashers, traffic lights, 3-color signaling, and a back-and-forth shuttle.  There will be a CD  handout and a door prize of a free LaunchPad at each session.

The Convention will be held April 26, 27 and 28th at:

Four Points by Sheraton Mississauga Meadowvale
2501 Argentia Rd.
Mississauga, ON
L5N 4G8  


Here's a link to the convention homepage:

http://streetsvillejunction.com/

Now for the not so good news.  I was asked by the organizers of the convention to show them where they could purchase some LaunchPads to have in stock at the Credit Valley hobby shop for the convention.  I went to TI's site for the LaunchPad and the LaunchPads were out of stock with a four week expected delivery.  That's not too unusual.  What was news is that TI's price is now $5.  I was wondering how TI could produce the LaunchPad for $4.30, so the price increase is not surprising.  

Credit Valley Railroad Company will have LaunchPads in stock for the convention.  Which is convenient for Canadians as you will not have to deal with exchange, customs and shipping.

If, however, you live in the US and you want to snag some LaunchPads at something like the old price, Newark and Mouser have them in stock.  

As of yesterday, Newark Electronics has 347 in stock at $4.35 ea.

http://www.newark.com/texas-instruments/msp-exp430g2/msp430g2xx-launchpad-flash-emulation/dp/77R3863
 

Mouser Electronics has 6281 in stock at $4.60 each:

http://www.mouser.com/ProductDetail/Texas-Instruments/MSP-EXP430G2/?qs=sGAEpiMZZMv1ORdfpzTN%252bMwZ3%252b5KGk2B


Mouser is actually cheaper if you select US Postal service for shipping.  I ordered another dozen for myself (and to populate the display I intend to build)While I hate to see the price go up because the $4.30 price was so unbelievable; I'll chalk it up to the devaluation of the US dollar.

Saturday, February 23, 2013

Drive External Loads with your LaunchPad

Until now all of our projects with the LaunchPad have been used to flash LEDs.  But what if you need to control a load heavier that the 25 milliamps at 3V, which is the maximum current available on any LaunchPad output pin?  Here's a way to control loads as high as 10 amps using modules that you can buy on-line.

The various Arduinos are a series of microcontroller boards not unlike the LaunchPad (but more expensive) they are probably the most popular microcontrollers with the 'hacker' and 'maker' communities.  These guys build all sorts electronics-based of projects, mostly robotics; and, if you know where to look, there are a large number of Arduino-compatible modules available that perform all sorts of functions.  These functions include various sensors (infrared, acoustic, temperature, attitude, light level), GPS, motor controllers and, the subject of this post, relay modules.  The Arduino community calls these add-on boards "shields" (don't ask me why, I don't know).  Although these add-on modules are made for the Arduino, most will work with the LaunchPad with no, or only slight, modification.






Here are three relay boards that I bought on e-bay last year for another railroad related project.  The most expensive of these was about $4.88 (last year, $5.88 this year), the least expensive was under $3.  They all have the same 10 amp SPDT relay mounted on them, they all operate on 5VDC (more on that later), they all operate on an 'active low' signal, and they all are "opto-isolated".

An opto-isolation circuit means that the trigger signal from the microcontroller passes through a chip where it lights up an internal LED.  The LED illuminates an internal photodetector; the photo detector, in conjunction with other circuit elements, generates the current to throw the relay.  In this manner the microcontroller does not have to source or sink enought current to drive the relay directly.

Here's where the LaunchPad, being a low-power design, might be at a disadvantage relative to other microcontrollers like the Arduino.  I said that these relay modules required 5VDC. The LaunchPad runs on 3VDC.  So while a 5VDC microcontroller like the Arduino can drive these directly, the 3VDC LaunchPad may require some assistance to drive these relay modules.

Before I decided I needed to supply an external source of 5VDC to the relays, I decided to try them on the 3VDC available on the LaunchPad and, eureka, it worked with all three relay modules.

Here's the hookup that you have to use:


The Vcc pin in the lower right of the LaunchPad should be connected to the Vcc pin on the relay module.  Similarly the GND pin on the LaunchPad should be connected to the GND pin on the relay module.  The input pin on the relay module can be connected to any output pin on the LaunchPad (if you want to do a quick demo connect the input to Pin 2 (Port 1,0) or Pin 14 (Port 1,6) which are driving the on-board LEDs). 

Now when the output pin to which the relay is connected goes LOW (that is to ground), the relay will pull in with an audible click and illuminates the LED on the relay module.  The relay does not pull in very enthusiastically on 3V, but it always pulls in and holds so long as the LaunchPad pin remains low.

Here's a video of all three of the relay modules shown in the first photo being activated in sequence by the LaunchPad.


It's unusual that three different relay modules, all rated for 5VDC also all run on 3VDC.  Well, maybe not so strange, the circuitry on each module is very similar if not identical.

To manipulate the LaunchPad's pins, I programmed Bill Hastings sequencer program.  The command sequence that I used is:

    P1_ALL_ON;
    P1_BIT_TOGGLE(BIT6);         // Bit 6 OFF
    DELAY_SECS(3);                   // wait 3 second
    P1_BIT_TOGGLE(BIT6);        // Bit 6 ON
    P1_BIT_TOGGLE(BIT4);        // BIT 4 OFF
    DELAY_SECS(3);                  // wait 3 second
    P1_BIT_TOGGLE(BIT4);       // Bit 4 ON
    P1_BIT_TOGGLE(BIT5);       // BIT 5 OFF
    DELAY_SECS(3);                 // wait 3 second
    P1_BIT_TOGGLE(BIT5);      // Bit 5 ON and go back to                                                //the beginning
 

You may notice the first command P1_ALL_ON does not require the parenthesis as shown in Bill Hastings original posting [P1_ALL_ON()]. Remember, these relay modules work when the pin is pulled low; so turning the pin OFF per Bill's program, causes the relay to activate.  The relays have SPDT contacts so if you are just using these to turn external loads on and off, there's always a set of contacts with the right sense.

I do not know how many of these relay modules a LaunchPad can drive simultaneously; probably at least a few.  If you do not want to have to worry about overloading your LaunchPad, you can provide external 5VDC by following this schematic.


If you power the relays this way, their operation will be snappier and you will not have to worry about the LaunchPad supplying power for the relays.  The 5VDC has to be reasonably clean because of the opto-isolator chips on the relay modules; the output of a power pack set for 5V will not do. Note that the ground of the LaunchPad and the ground of the external power source must be connected together for this to work.

So where do you get the relay modules? Last year, when I bought my relay modules, they were listings from various sellers on e-bay.  At the time of this writing, only one of the original modules is still listed on e-bay in the seller's store.  It's the largest relay module at the top in the video.  You can find it here: relay module.   The price this year is $5.88 and it's not a bargain, you can do better.

If you search e-bay's listings and the e-bay stores of vendors of hobbyist electronics, you can find a lot more at better prices.  Here's a two-channel relay module for only $2.98: 2 channel relay module  Hookup to this module will be a little bit different because it has two input pins, one for each relay.  

You'll notice the title of this e-bay listing: "5V Two 2 Channel Relay Module With optocoupler For PIC AVR DSP Arduino ARM"  It contains a number of clues that indicate that this unit should work with the LaunchPad.  First off, it's rated for 5V; this is essential as there are nearly identical 12V and 24V relay modules listed on e-bay.  Then notice that it lists "PIC AVR DSP Arduino ARM". All of these are other microcontrollers or Systems on a Chip (SoC).  When you see this listed, there's an excellent chance that it will work with the LaunchPad.  So if you search e-bay for "relay" then key-in on the listings that list "5V", "microcontroller" or any of the specific microcontrollers listed above, you should be OK.

All of these relay modules listed on e-bay will ship directly from the vendors in China - even if they claim that the merchandise is in the US. This has not been a problem for me; but you have to keep two things in mind.  First, the "free" shipping will take about 3 weeks.  Not a problem if you are aware of that.  However, there is a lot of variability in shipping time, and most of the vendors will advise when your package ships, but they cannot tell you when it will arrive.  Second, use only Pay Pal to pay for your purchase.  With Pay Pal, the overseas vendor never gets your credit card number; so it's safe.  With Pay Pal you have recourse if your merchandise does not arrive or it is not as advertised.  The vendors do not want to lose their Pay Pal accounts and, therefore, they do not play games with your order.

If this has not raised any red flags (pun intended), then you can also go directly to some vendors in China and skip e-bay.  I've had good results with Good Luck Buy and Deal Extreme.  These vendors have lots of these relay modules in configurations from 1 to 16 channels.  Here are a couple:  identical relay module  this appears to be identical to the $5.88 module listed above; one channel module without opto-isolation without the opto-isolation, this one may not work on 3VDC, but at $1.64 you can afford to experiment; here's the cheapest 8 channel unit that appears to include opto-isoation 8 channel relay module; and it's rated highly by the users.  Remember a multi-channel relay module will require wiring to multiple output pins on the LaunchPad.


Good Luck Buy and Deal Extreme are not manufacturers and their merchandise changes periodically. So if you find something that you like, don't hold up your re-order. The rules for ordering from China apply here too.     

If you are not comfortable with ordering from China, then you can find similar items (at higher prices) from the hacker/maker websites.  And Amazon actually has some of theseHere are 8-channel and 2-channel modules that ship from Amazon 8 channel module from Amazon  2 channel module at Amazon  

About the only significant differences I can see between all of these modules is that some use PC pins for the connection to the microcontroller and some, like all of the ones that I bought, use screw-terminals.  All of the relay modules seem to use screw terminals for the connections to the relay.  These modules are so inexpensive, it does not pay to fool around with individual relays.  They also have diodes to protect against switching inductive loads (you don't need to know what that is, but you do need the diodes). So unless you know how to hook up individual relays, stick with these modules.

Well, as usual, I've run very long with this post.  So enjoy switching heavy loads with your LaunchPad.



 


Friday, February 1, 2013

Bill Hasting's Environmental Sequencer

Moderator's comment: Here's a program that is an elegant solution to providing a sequencer that will turn pins on the LaunchPad on and off in any sequence and with arbitrary time delays between.  The pins going high (on) and low (off) can be used to light LEDs or activate things like external relays.  Let's hear Bill tell all about it. 



Environmental Sequencer
Code and pictures by
 Bill Hastings


Overview

This project started out as a lighting simulator, but quickly turned into a general purpose, time based sequencer.  Using it, I've written a simple two-light flasher, two-way traffic lights, chasing light marquees, and simulated house lighting.  One of the goals was to write it to make it fairly easy for non-coders  to create custom sequences.  I've reduced the instruction set to a small set that allow for turning pins on, off or toggled and adding delays.


Technical Info

I've not included a schematic since this was made to be general purpose.  I have included a couple of sample sequences for you to play with.  The first is an alternating flasher that uses the on-board LEDs.  The second is a two-way traffic signal.

I have avoided using names like LED for pin names, since the output can be used to control equipment other than lighting.  I have used the terms ON and OFF to signify HIGH and LOW respectively.

I have used macros (don't worry if you don't understand that) to replace arcane instructions for accessing the I/O.  For example, instead of P1OUT |= BIT0 to turn P1.0 ON, you can now use, "P1_BIT_ON(BIT0)".

Available sequence instructions are:


  • P1_ALL_ON() - Turn all Port 1 pins on (high)
  • P1_ALL_OFF() - Turn all Port 1 pins off (low)
  • P1_BIT_ON(BITx) - Turn Port 1 bit x on (high)
  • P1_BIT_OFF(BITx) - Turn Port 1 bit x off (low) 
  • P1_BIT_TOGGLE(BITx) - Toggle state of Port 1 bit x


  • P2_ALL_ON() - Turn all Port 2 pins on (high)
  • P2_ALL_OFF() - Turn all Port 2 pins off (low)
  • P2_BIT_ON(BITx) - Turn Port 2 bit x on (high)
  • P2_BIT_OFF(BITx) - Turn Port 2 bit x off (low) 
  • P2_BIT_TOGGLE(BITx) - Toggle state of Port 2 bit x


  • DELAY_TENTHS(X) - Provide a delay of x tenths of a second
  • DELAY_SEC(X) - Provide a delay of x seconds
  • DELAY_MIN(X) - Provide a delay of x minutes

The default low frequency clock runs at a modest 12000 Hz.  Unfortunately, it is not very stable and can vary from 4000Hz to 20000Hz, depending on temperature and other environmental conditions.  If you require more precise timing, a crystal is provided with the LaunchPad kit, but your need to solder it in yourself.  Google "MSP430" and "crystal" and you'll find plenty of articles on how to install the crystal.  Once installed, you need to modify the main.c file and uncomment the "//#define USEXTAL" by removing the 2 /'s at the beginning of the line.  It should look like this "#define USEXTAL".  



The theory of operation is pretty simple.  Output pins are set to either ON (high) or OFF (low).  When a delay is requested, Timer A continuously increments a counter every 0.1 second. The delay routine waits for the requested time to elapse, then returns so that the next sequence instruction can be executed.

Future

  • Use multiple timers, allowing for asynchronous executions.
  • Ability to turn on/off specialty lighting effects like Hoffy's welder or fireplace lighting.
  • Please pass along any of your ideas.
  
Additional Moderator's comments: Although Bill is properly concerned about the accuracy of the timers if run without the crystal in place, for most model railroad applications using the LaunchPad as it comes should not be a problem.  Unless you are doing something requiring precise timing like a speedometer or, possibly, a fast clock, approximate times should be sufficient. 

Bill's code is very heavily commented (the sign of a veteran coder) so refer to the code itself for most of the information that you would need to understand it or modify it. 

However, for the non-coders, you will want be able to change the sequences programmed into this code to suit your application.  Look towards the end of the code for these two markers:

// BEGIN ##### 
 
 
 
// END #####

These two lines are comment lines (they begin with the double slash "//") that Bill has used to mark the place in the code where the instructions to turn pins ON and OFF should  be locatedBetween these two markers you will find additional comments by Bill to help you understand how this works.  Then you will come across this series of instructions:

// Simple 2 light flasher example - Uses onboard LEDs on P1.0 and P1.6
 P1_BIT_TOGGLE(BIT0); // green LED on
 DELAY_SECS(1);  // wait 1 second
 P1_BIT_TOGGLE(BIT0); // green LED off
 P1_BIT_TOGGLE(BIT6); // red LED on
 DELAY_SECS(1);  // wait 1 second
 P1_BIT_TOGGLE(BIT6); // red LED off and go back to the beginning

The first line is a comment, of course.  Then begins a series of the instructions that Bill has developed.  Earlier in the program, all pins have been turned OFF, so the first instruction:
 
P1_BIT_TOGGLE(BIT0); // green LED on

"toggles" (that is, reverses the state of) Port 1, Bit 0 (found on pin 2) from OFF to ON.  This port/pin is the one that drives one of the on-board LEDs.  The next instruction:

DELAY_SECS(1);  // wait 1 second

delays for 1 second.  The following instruction:
 
P1_BIT_TOGGLE(BIT0); // green LED off

"toggles" the same port/bit/pin from ON to OFF.   And so on with the next instruction working on the other on-board LED. The LEDs are thereby turned on for one second, turned off and the other turned on, and off, etc. indefinitely.   BTW Bill has his red and green LEDs reversed in the comments to this section of the code (green is red and vice versa).  

To show how this works, I changed the timing in the first 'delay' instruction to 5 seconds on, by changing it to the following:
 
DELAY_SECS(5);  // wait 5 second
 
while leaving the green LED at 1 second.  The asymmetric flashing that this produced is shown in the video.

 



When you are ready to create your own sequences, you'll delete all of the instructions in the block above and replace them with instructions chosen from the list given in Bill's write-up or the same list in the comments embedded in the code.

When you add your own instructions to create your own sequences be sure to include the semicolon at the end of the executable part of the instruction and the "//" before your comments, if any.  For example the instruction as written in Bill's write-up:

P1_ALL_ON() - Turn all Port 1 pins on (high)
 
Should be entered into the code like this: 

P1_ALL_ON();   //Turn all Port 1 pins on (high)

 Notice the semi-colon  and the // added before the comment part of the line. 

Bill has provided an additional way to get your instructions into the code.  The instructions can be written into a text file and then the file is "included" via the "#include" directive.  In the section of the code between the //   BEGIN ##### and the //   END ##### you will find these instructions which have been commented  out:


 
// example of separate file inclusion
//#include "simple_flasher.esq"

The .esq file type is Bill's invention to hold instructions for his sequencer code. Bill has provided files for the alternate flasher, and a traffic signal.  These can be found here:

 

To include the instructions as a file: remove any in-line instructions; uncomment the #include statement; make sure that the include statement has the name of the file that you want to use; and make the file available to the compiler.   Code Composer Studio creates a workspace on your computer's disk entitled "workspace_v5_2" (for the current version of CCS).  In that directory you will find a folder that bears your project's name.  Drop the .esq file into that folder.  Build the project per normal and the compiler inserts the instructions form the file in-line during the compile process.  The code will now execute the instructions from the file.

Bill's .esq file format will be a way that people can exchange instructions for his innovative sequencer in a ready-to-use format.

The code file can be found here:



The code listing follows.




/*******************************************************
* Environmental Sequencer
*
* COPYRIGHT © 2013 Bill Hastings
*
* Provided under a Creative Commons Attribution, 
*  Non-Commercial Share Alike,3.0 Unported License
*
* TARGETED TO MSP430 LANUCHPAD 
* W/MSP430G2553 PROCESSOR
*
*****************************************************/

#include <msp430g2553.h>

//#define USEXTAL // uncomment this line to use the crystal clock
#ifdef USEXTAL
#define TRIGGER 3277 // 1/10 of crystal frequency 32768Hz
#else
#define TRIGGER 1200 // 1/10 of nominal VLO frequency 12000Hz
#endif

// pin access macros
#define P1_ALL_OFF P1OUT = 0
#define P1_ALL_ON P1OUT = 0xFF
#define P1_BIT_ON(bit) (P1OUT |= bit)
#define P1_BIT_OFF(bit) (P1OUT &= ~bit)
#define P1_BIT_TOGGLE(bit) (P1OUT ^= bit)

#define P2_ALL_OFF P2OUT = 0
#define P2_ALL_ON P2OUT = 0x3F
#define P2_BIT_ON(bit) (P2OUT |= bit)
#define P2_BIT_OFF(bit) (P2OUT &= ~bit)
#define P2_BIT_TOGGLE(bit) (P2OUT ^= bit)

// delay macros
#define DELAY_TENTHS(delay) doDelayTenths(delay)
#define DELAY_SECS(delay) doDelayTenths(delay * 10)
#define DELAY_MINS(delay) doDelayTenths(delay * 10 *60)

// routine definitions
void doDelayTenths(unsigned long delay);

// global(s)
volatile unsigned long counter = 0;

// main routine
void main(void) {

// initializations
 WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

 P1DIR = 0xFF;  // Set all P1 pins to output
 P1_ALL_OFF;  // Set all P1 pins off

 P2DIR = 0x3F;  // Set all P2 pins to output
 P2_ALL_OFF;  // Set all P2 pins off

#ifndef USEXTAL
 BCSCTL3 |= LFXT1S_2;  // use VLO
#endif

 TA1CCR0 = TRIGGER;  // Count limit (16 bit)
 TA1CCTL0 = CCIE;  // Enable Timer A1 interrupts
 TA1CTL = TASSEL_1 + MC_1; // Timer A1 with ACLK, count UP

 _BIS_SR(GIE);   // interrupts enabled

// run loop
 while(1)
 {
/*
* Available sequence instructions are:
*  P1_ALL_ON() - Turn all Port 1 pins on (high)
*  P1_ALL_OFF() - Turn all Port 1 pins off (low)
*  P1_BIT_ON(BITx) - Turn Port 1 bit x on (high)
*  P1_BIT_OFF(BITx) - Turn Port 1 bit x off (low)
*  P1_BIT_TOGGLE(BITx) - Toggle state of Port 1 bit x
*
*  P2_ALL_ON() - Turn all Port 2 pins on (high)
*  P2_ALL_OFF() - Turn all Port 2 pins off (low)
*  P2_BIT_ON(BITx) - Turn Port 2 bit x on (high)
*  P2_BIT_OFF(BITx) - Turn Port 2 bit x off (low)
*  P2_BIT_TOGGLE(BITx) - Toggle state of Port 2 bit x
*
*  DELAY_TENTHS(x) Provide a delay of x tensths of a second
*  DELAY_SECS(x) Provide a delay of x seconds
*  DELAY_MINS(x) Provide a delay of x minutes
*
* Things to remember:
*  1) To use the crystal clock, you must uncomment "//#define USEXTAL" (line 14), 
*  AND have installed the crystal on your LaunchPad
*  2) When editing your sequence, CASE IS IMPORTANT 
*  - p1_all_on() does not equal P1_ALL_ON()
*  3) When using the P1_BIT calls, the argument should only use BIT0 through BIT7
*  4) When using the P2_BIT calls, the argument should only use BIT0 through BIT4
*  5) Multiple BIT arguments can be specified for P1_BIT 
*  and P2_BIT operations. For example, if you wanted to turn on both
*  BIT0 and BIT6 on P1, you could use, "P1_BIT_ON(BIT0 + BIT6);"
*  6) Inline sequence instructions should go between the lines
*   "// BEGIN #####" (line 101) and "// END #####"
*  7) Use "#include "<filename>" to include sequence instructions from a separate file
*  8) Complete each instruction line with a ; (semi-colon)
*  8) All output pins start in the off (low) state
*/

// BEGIN #####

/*
 * Below are examples of both file-based and inline sequences
 * Currently it is using inline. To use file-based inclusion,
 * comment out all of the inline instructions, and uncomment
 * the #include "simple_flasher.esq". To go back, just reverse
 * it - uncomment the inline instructions and comment the
 * #include.
 */

// example of separate file inclusion
//#include "simple_flasher.esq"

// example of inline instructions
// Simple 2 light flasher example - Uses onboard LEDs on P1.0 and P1.6
 P1_BIT_TOGGLE(BIT0); // green LED on
 DELAY_SECS(1);  // wait 1 second
 P1_BIT_TOGGLE(BIT0); // green LED off
 P1_BIT_TOGGLE(BIT6); // red LED on
 DELAY_SECS(1);  // wait 1 second
 P1_BIT_TOGGLE(BIT6); // red LED off and go back to the beginning

// END #####

 } // end while
}  // end main

// delay by x tenths of a second
void doDelayTenths(unsigned long x)
{
 counter = 0;
 while(counter < x) {}
}

#pragma vector=TIMER1_A0_VECTOR    // Timer1 A0 interrupt service routine
__interrupt void Timer1_A0 (void)
{
 counter++;
}



 .