HOME  >>  ARDUINO HOW TO MENU >>  Delicious.Com Bookmark this on Delicious   Recommend to StumbleUpon

Loom control

"Finished" software which could be taken further

This is NOT typical of Sheepdog Software online code. But, like all such, at least in trial versions, it is free.

The code presented here is intended to run a loom. It can be adapted to other things. I was thinking I might hook it up to some wind chimes? It also demonstrates some general programming ideas.

It isn't polished. If you don't want to copy/paste the code further down the page, you can download the sourcecode as a .zip file, with an Arduino .ino file in it.

The code works... up to a point. Not the point where things were so unraveled that I couldn't face extra work. It is still very much "under control". But I ran out of time.

What it currently does

I will start by telling what the software currently does. Then, to help explain the "bleeding chunks" of remmed out code, I will explain what it did... and could do again, with little effort.

The software was written to run in an Arduino Mega, to give access to large numbers of digital outputs. But it can be tested something as simple as an Pro Mini.

Be careful when you hook up the actuators that you do not exceed the device's power limits. What actuators you use will matter in that consideration

The lines like...

char Pat0[]="0101010101010101010101010101010101010101";
char Pat1[]="1010101010101010101010101010101010101010";

... are at the heart of the program. There should be 40 1s and 0s in each.

The Arduino is hooked up to a loom, with actuators on each of the loom's warp lifts. As written... easily extended... it can control 40 warp lifts.

If Pat0[] and Pat1[] were set up as above, (and bLastStepToDo set to 1. More on bLastStepToDo in a moment!), then the loom would weave the simplest sort of cloth ever designed.

But! You can have more pattern-of-lift strings than just Pat0[] and Pat1[]. In the present form of the program, most of what you need for strings up to Pat7[] (an eighth pattern) is provided. In some cases, those things look like...

.... 2:strcpy(LPat,Pat2);break;
case 3:strcpy(LPat,Pat3);break;
case 4:strcpy(LPat,Pat4);break;
//...etc... i.e. there will be more like
//     the above for fabrics made
//     with longer sequences of patterns.

... but those things should not cause the intermediate Arduino programmer any real hassle. If you ARE having hassle, be careful... the program doesn't need radical surgery for "basic" operation.

If you want to go beyond the simplest possible design, you need to change waht bLastStepToDo is set to. (It is set once, and then not changed.)

If you wanted, say, 4 patterns of lifts to be set on the warps, and then that sequence to repeat over and over, you would set bLastStepToDo to ** 3 **... one less than the number of patterns to be repeated.

There are stubs in the program to allow you to specify how many steps comprise the sequence by simple toggle switches on swNumSteps0, swNumSteps1, swNumSteps2.

So... we have a basic plan. Just before I move on: To test this, to "see what it might do", without the hassle of building a loom, hooking up warp lifts. Oh, and buying a Mega... put it in a "little" Arduino with LEDs (with the usual resistors) on pins 6, 7, 8 and 9. They should wink on and off in response to the 6th, 7th, 8th and 9th 1s and 0s in Pat0[], Pat1[], etc. (The first 5 warp lifts were assigned to pins 41-45... luxuries available only to Mega owners... to free pins 0-5 for other purposes.)

You will also need to fit a momentary switch to pin 2. That's for swFrmLoom, and we'll come to the "From Loom" part in a moment.

The switch should connect the pin to the Arduino's ground when closed. The pin's input can float (as far as external components are concerned, anyway) when the switch is open. (See pinMode(x,INPUT_PULLUP), a "new" feature in Arduino 1.0, but merely making convenient something we could always do.)

That's all you need... four LEDs, four resistors, one switch.

What about all the other "stuff". Don't worry. The program will work fine, with nothing on the other lines. The Arduino won't be harmed. (There should be NOTHING on the other lines. (the standard LED on pin 13 is okay) I can't promise you what will happen if you run the program with bits of your previous project still hooked up!)

How it works.... NOW...

You will see vestiges of various things in the code, as it stands in the .zip file... well, as it stood when I wrote that. I'm not always good about editing web pages, but if the "vers" ID is still "23 Mar 15b" it probably IS as follows!...

The program was written in England... to be installed on a loom in France! So I, the writer, can't be 100% sure as to how everything turned out, but I do know what happens if you run it as follows...

Start the program. Notice the LEDs. They should be in step with the corresponding ones and zeros in Pat0[].

Press and release the momentary switch.

The LEDs should now be in step with Pat1[]'s 1s and 0s

Press and release the momentary switch.

The LEDs should now be in step with Pat2[]'s 1s and 0s

Press and release the momentary switch.

The LEDs should now be in step with Pat3[]'s 1s and 0s

Press and release the momentary switch.

Assuming that the line....


Hasn't changed, the LEDs now should be back to where they started... on and off (or perhaps the inverse of that) to reflect the 1s and 0s in Pat0[].

And thus it would go on, for as long as you care to keep pressing the switch.

Simples, really. If the above doesn't seem simple, go through it a few more times. Trace out what is in the program. It is... really!

Perhaps I should say a bit about the loom?

It has 40 "warp" threads. It has a mechanism to selectively lift these. For a simple fabric, you would first lift, say, all the even warp threads. The ones numbered 0, 2, 4, 6, etc. Then you would "throw" a shuttle across, in the space between the raised and not-raised threads. This would put one strand of "woof" thread into your piece-of-cloth-in-the-making, at right angles to the warp threads, which is, of course, part of what makes "woof" threads woof threads!

You would then let the even warp threads down, and lift up all the odd warp threads. And throw the shuttle again. Two woof threads in place.

And do that over, and over, and over! So far so good?

The loom the program controls has mechanical linkages to "throw" the shuttle for you periodically. The only "trick" is to be sure that the right warp threads are lifted at the time... and that they stay lifted long enough for the shuttle to make it across between the (currently) lifted warp threads (and un-lifted ones).

The whole mechanism is run by a hand crank or single electrical motor. Sadly, small boys, so suited to this and things like operating blacksmith's bellows and sweeping chimneys, are now-a-days required to be in schools torturing the people who would like to teach them.

Happily, there is a "thingie" which goes up and down, and it can be used to "press" swFrmLoom, the "change the warp lifts NOW" button, which we were pressing by hand, in the scenario above.

And that's how the code works, now.

At one time, I was unaware of the mechanics. In any case, I wanted a way to move things along "stepwise", for debugging work. ORIGINALLY... not now... there was a switch on swCont. When it was in one position, the program ran "Continuously"... which, in those days, meant go 'round and 'round the process, with a fixed interval between warp lifts. It would be easy to convert the program back, to restore this mode, but that would only be useful if your loom had a "throw shuttle" mechanism which could be triggered by an electrical signal... which could be sent from the program at the right moment. There ARE scraps of the "run continuously" mode in the program. There are NO scraps of a "trigger throw shuttle" output's management.

In the days when swCont was part of the solution, there was another switch, swStep. When swCont was not set to "run continuously", the warp lifts did nothing... until you pressed swStep. And then they would change to the next pattern. Release swStep: Nothing further happened. Press it again... and you got the next pattern.

In a perfect world, I would re-write the program thus...

swCont would make the program either lift the warps as directed (see below) or stop them being lifted at all. Call it sort of an "on/ off" switch. Although with some looms, "stuff" would continue to happen, you just wouldn't get any changes in the warp lifts. However, if swCont was in the "off" position, a positive edge on swStep would cause the warp lifts to change to the next pattern.

There be another toggle switch, a "selector" switch, which would select between "run the way it runs now" (with warp lifts happening in response to inputs on swFrmLoom) and "run at a steady frequency, but also generate "throw shuttle" signals.

All of that could probably be done JUST by minor revisions within the loop() subroutine. And maybe a few functions to test the state of the new switches, or generate the "throw shuttle" command. MOST of the program, the HARD parts of it, is/ are done!

Two easy-to-implement frills... bits of what you need are already in the program...

It would be nice if the program were to "tell" you what step in the repeating sequence of patterns the loom had reached. This could be displayed on doLED0, doLED1 and doLED2. ("do" for Digital Output", by the way.)

It would be nice if there were a way to "set" bLastStepToDo without reprogramming the Arduino. Again, adding that would be quite simple, and bits of what you need are already in the program. That's the only thing that the pins swNumSteps0, swNumSteps1 and swNumSteps1 were set up for.

So! There you have the description. Here's the code!....

(There's nothing profound after the code, just a "goodbye", to wrap things up, and various "routine footer" things like my contact details.)


Arduino Loom controller from SheepdogSoftware.co.uk- Type "A"
ver 23 Mar 15b.. POST the one sent to HL 8:30am 23 Mar 15, "final"
started 06 Mar 15


A program to control the lifting of warps as a loom
operates. Quite "poetic", actually... every introductory
computer studies course will tell you that the first
programmable machine was Jacquard's loom, which was
controlled by punch cards. I have seen such looms still
in use in Indian artisan mills. And, with this, we come
full circle: Back to a programmable loom, but with
somewhat more sophisticated controls, even if, in
general principle, all we have replaced is the cards,
using patterns of bits in an EEPROM.

The program is expected to run on an Arduino Mega.
For development work with more modest hardware, all
that is lost is the ability to control large numbers
of warp lifts.

Below here: scraps of old comments, for when Stepwise
reinstated, etc.

The software lets the loop operate "stepwise"... i.e. operator
has to flip a switch to make it move on, change the warp lifts 
to the next pattern, or "continuously"... it just "goes", with
a fixed delay between warp lift patterns.

The delay between lifts could be controlled by a potentiometer...
a thing like an old fashioned volume control on an old fashioned 
radio, i.e. a knob you rotated one way for louder, other way for softer.

Almost any pot would do. I would guess linear would be best. Total 
resistance between (inclusive) 1k and 33k.

This would go on one of the Arduino's analog input lines.



v v v v begin: TKB notes to self:  v v v v
In tut, discuss ways to make "up" and "down" codes
defined once, and flexible.

Discuss pros and cons of using a binary number for
the pattern codes instead of string of chars

^ ^ ^ end: TKB notes to self ^ ^ ^ ^

/*How digital I/O lines are used in the program....
D0 and D1 are left unused to stay clear of comms with development PC
D2 to D5 used for special I/O for user interface
    and loom control lines.*/
//"Special" inputs/outputs...

#define swFrmLoom  2 //Pin on which pulses from loom arrive.
//   Normally open circuit or high, if this is grounded,
//   is is "saying", "change the pattern on the lifts" when
//   loom in continuous mode.
//The "stepwise" mode which was once available could be re-instated,
//   but isn't available at the moment.

#define swCont  3 //Pin toggle switch "Continuous/Stepwise" is on
/*Set one way, and the loom runs continuously. Once upon a time,
  when set the other way, it stopped the program after each
  pattern was set until the "Step" switch is changed
  to it's other position. That mode of operation could be
  re-implemented, but isn't available at the moment.
This switch also works as a "start/stop" switch. If the loom
  is in "Stepwise" mode, then (once stopped) after each pattern
  until the "Step" switch is changed to other position, so
  it stops repeatedly. If the loom is in "Continuous" mode,
  it is only necessary to switch it to "Stepwise" mode to
  stop it.*/
#define swStep  4 //Pin toggle switch "Step" is on.
  //TKB note to self: This being on 4 makes the prgm NoviceGuard

//Reserved for future expansion...
#define doLED0 50 //First of three LEDs, for "Which Pattern" display
#define doLED1 51
#define doLED2 52
//Maybe one more... D53 reserved for that.

//Reserved for future expansion...
#define swNumSteps0 54 //Not in use yet... will allow
#define swNumSteps1 55 //shorter-than-maximum pattern
#define swNumSteps2 56 //cycles
//Maybe one more. D57 reserved for that.

/*From D6, relays assigned Relay6->D6, Relay7->D7, etc.
   (I.e. sixth relay is assigned to the Arduino's digital pin "6".)  
Relays 1 (the first one), 2, 3, 4 and 5 on lines 41,42,43,44
    and 45 in Arduino Mega version of software.
"Moving" a relay to a different pin is trivial... unless you
   move it to a pin already being used for something else! Of
   course, "moving" the pin in the software must be reflected
   in hardware changes, too.
   Even if you move a relay to an already used pin, you can
   usually move the OTHER thing, subject to the same caveat.
   All done with the #define lines.


#define doRelay1  41 //Pin first warp solenoid relay is on
#define doRelay2  42
#define doRelay3  43
#define doRelay4  44
#define doRelay5  45
#define doRelay6  6
#define doRelay7  7
#define doRelay8  8
#define doRelay9  9
#define doRelay10 10
#define doRelay11 11
#define doRelay12 12//May be over-ridden by TKB debugging
#define doRelay13 13//  code... see re-defines below. (12&13)
#define doRelay14 14
#define doRelay15 15
//....etc for as many relays as are present... up to....
//....#define doRelay40  40
//(Many pins above 40 are in use for other things

//THE "standard" PINS.
//(If this block enabled, it is NOT necessary to DIS-able
//   the earlier defines of these pins. They are simply
//   over-ridden.)
/*Add / in front to rem out start of rem out!
#define doRelay5  5//Pin first warp solenoid relay is on
#define doRelay6  12
#define doRelay7  13

byte bStepSwPrevState;//Holds 0 if boStep was low, 1 if it was high
//Use of a byte-type variable (instead of a boolean) connected with
//   the need to de-bounce input from swStep, and the way that is done.

byte bPat;//Contents will determine which pattern is being done
//at the moment... Pat0, Pat1, etc.

//Init value: just a placeholder. 40 1s and 0s
char LPat[]="1111100000111110000011111000001111100000";

//char Pat0[]="1111100000111110000011111000001111100000";
//char Pat1[]="1111100000111110000011111000001111100000";
//char Pat2[]="1010101010101001010101010101010101010101";
//char Pat3[]="1001010101010101010101010101010101010101";

//Alternate set of patterns... Only one can be enabled at one time.
char Pat0[]="0111110000000000000000000000000000000000";
char Pat1[]="1011101000000000000000000000000000000000";
char Pat2[]="1101011000000000000000000000000000000000";
char Pat3[]="1110111000000000000000000000000000000000";
char Pat4[]="0000000000000000000000000000000000000000";
//end debugging block

The ones and zeros stand for "this warp lifted/ not lifted",
   or possibly the inverse. ("1" MAY be "lifted", or maybe it
   is NOT lifted. "0" will, however, be the other.
The first character in the string defines state of relay1,
   the second that of relay2, etc.
It wouldn't be hard to change the program to use
   different characters (+ and - ?), if that would make
   visualizing the overall result easier.
"1" may mean "warp lifted"... or it may mean "warp NOT lifted".
   If it matters, the programming could be changed. ("1"="lifted"
   has the virtue that "1" also means "relay energized".)
Yes: For those who know, arrays would be more elegant-
  and more difficult for novices.*/

byte bLastStepToDo;//See note in setup() for what this controls.

//This was only true when "continuous" meant "continuous at a
//  constant frequency". If the old stepwise is re-implemented,
//  part of that will be to include two types of "continuous"...
//  One moderated by signals from loom, one which will be
//  controlled by bDelayBetween.
byte bDelayBetween=200;//If this is set to 200, there will
//      be a 0.2 second (200 milliseconds) delay between warp
//      lifts when the loom is running in "Continuous-constant
//      frequency" mode. (Change to an "int" type variable for longer delays)<< REMEMBER THAT MODE NOT AVAIL AT

/*======== Definitions of globals ends here.=========

void UpdatePatDisp(byte bLPat)//Update the display of
// which Patern is set on warps
//Still to be written... display bLPat on
//   "output device"... currently the 3 LEDs
//   on doLED0,doLED1,doLED2

}//End of UpdatePatDisp

void InitPins()//Called by setup()
pinMode(doRelay1, OUTPUT);digitalWrite(doRelay1, LOW);
pinMode(doRelay2, OUTPUT);digitalWrite(doRelay2, LOW);
pinMode(doRelay3, OUTPUT);digitalWrite(doRelay3, LOW);
pinMode(doRelay4, OUTPUT);digitalWrite(doRelay4, LOW);
pinMode(doRelay5, OUTPUT);digitalWrite(doRelay5, LOW);
pinMode(doRelay6, OUTPUT);digitalWrite(doRelay6, LOW);
pinMode(doRelay7, OUTPUT);digitalWrite(doRelay7, LOW);
//pinMode(doRelay8, OUTPUT);
//etc for as many relays as are present

pinMode(doLED0, OUTPUT);//For output of what step we
pinMode(doLED1, OUTPUT);//   are on.
pinMode(doLED2, OUTPUT);
//and maybe one more... probably no more than that
//The code to drive these not present yet, except
//   in "stub" form.

pinMode(swNumSteps0,INPUT_PULLUP);//For input of how
pinMode(swNumSteps1,INPUT_PULLUP);//  many steps make
pinMode(swNumSteps2,INPUT_PULLUP);//  up full cycle.
//and maybe one more... probably no more than that
//The code to read these not present yet, except
//   in "stub" form.


}//End of InitPins()

boolean boSetForStepwise()
//May need debouncing, to prevent "chatter" on switchover?
if (digitalRead(swCont)==HIGH)
 {return true;}
 {return false;};

void setup()

/*Determine what state swStep is in, and
  set bStepPrevState to the state it is NOT
  in so that on the first pass through loop()
  a cycle occurs.
  but, at least at one point, it all "worked"
  like this!)
  AT LEAST (inclusive) 1, CAN'T BE MADE TOO HIGH
bLastStepToDo=3;/*Determines the "steps" to be repeated...
  For only two warp patterns, set bLastStepToDo to 1.
  This will make loop set warp lifts to patterns defined
  in Pat0[] and Pat1[] over and over again.
For four patterns, repeated, set bLastToDo to 3.
  This will make loop set warp lifts to patterns defined
  in Pat0[], Pat1[], Pat2[], and Pat3[] over and over again.

Eventually, it will be possible to set the number of repeats
  with toggle switches on swNumSteps0, ..1, and ..2

There are no checks agaist you setting bLastStepToDo too high.
  If bLastStepToDo is set to, say, 7, there would need to be
  a Pat7[], but also parts of the code need to provide for
  the highest number used. Mostly (all?) this limit is in
  "case x:strcpy(LPat,Patx);break;"    .... part*/

delay(800);//To let things settle... the next step happens
//just as the system is powering up.

//See note A, a few lines below here...
if (digitalRead(swStep)==LOW)
  {bStepSwPrevState=0;}//no ; here

/*CARE: I thought following necessary. Not, for some
reason. (It is all only to do with getting the
program to set the first lift pattern on the relays
on boot, when the "Stepwise or Continous?" switch is
set to Stepwise"

if (bStepSwPrevState==0)

/*Note A: Yes...
If you wish to invert the signal,
the two parts above could be "compressed" into...

     if (digitalRead(swStep)==LOW)
        {bStepSwPrevState=1;}//no ; here

... but I wanted to stress that (I WAS... before remming out
the second part!...) setting bStepSwPrevState to the
code for the state the switch is NOT in.*/

bPat=0;//Start loop with Pat0 called for.  
}//End of setup()


void HeartOfActuatorUpDown(byte bWhichOutPutPin, byte bWhatLevel)
//This may seem "pointless"... but if later, different
//   actuators are used, which are not so easily
//   set to one state or the other, this abstraction may
//   be very welcome.
  if (bWhatLevel==HIGH)
}//end of HeartOfActuatorUpDown()

void ActuatorUpDown(byte bWhichAct,char cWhatState)
//Put an actuator into the state required by the
//   data which has been read
//Parameters: The first specifies which ACTUATOR,
//   The second specifies whether it should be
//   in "a" or "b" state... up/down, in/out, red/green...
//   whatever! (The second must be '1' or not '1')

  byte levTmp;
  if (cWhatState=='1') {levTmp=HIGH;}else{levTmp=LOW;};
  switch (bWhichAct)
    case 1:HeartOfActuatorUpDown(doRelay1,levTmp);break;
    case 2:HeartOfActuatorUpDown(doRelay2,levTmp);break;
    case 3:HeartOfActuatorUpDown(doRelay3,levTmp);break;
    case 4:HeartOfActuatorUpDown(doRelay4,levTmp);break;
    case 5:HeartOfActuatorUpDown(doRelay5,levTmp);break;
    case 6:HeartOfActuatorUpDown(doRelay6,levTmp);break;
    case 7:HeartOfActuatorUpDown(doRelay7,levTmp);break;
    default:break;//"Safe"... but not something 
                       //that will be noticed, if it happens.
  }//end of: switch/case
}//end of: ActuatorUpDown(posn, state)

void LiftWarps(byte bLPat)
//This can be done MUCH more elegantly...
//  but following should work!
//Use of LPat crude. Could be done better?

//Move to a "Tmp" variable: the correct pattern
//  for the current STEP in the sequence of
//  patterns which define the overall design
//  of the fabric being woven.

switch (bLPat) {
case 0:strcpy(LPat,Pat0);break;
case 1:strcpy(LPat,Pat1);break;
case 2:strcpy(LPat,Pat2);break;
case 3:strcpy(LPat,Pat3);break;
case 4:strcpy(LPat,Pat4);break;
//...etc... i.e. there will be more like
//     the above for fabrics made
//     with longer sequences of patterns.
};//End of "switch")

//* Next could be done more elegantly, too...

//N.B.: Here we have a minor "lack of logic" between the
//array "numbering" (zero based), and the numbering of the
//relay channels (1 based).
//YES... the following IS right!...
//  Relay**1**] is controled by LPat[**0**], etc.

//Now set the different actuators to the state called for
//  by one of the characters in the "Tmp" variable holding
//  (Ummm... is "Tmp" still in use?)
//  a pattern of "ups and downs", "ins and outs", "ons and offs"...
//  whatever words are appropriate to the device the
//  hardware is driving today....

ActuatorUpDown(1,LPat[0]);//Yes... 1 and 0, because one counts
ActuatorUpDown(2,LPat[1]);//   from zero, the other from 1.

vvv Start TKB NOTE TO SELF...

Scraps to be used in more elegant solution...

for (byte i=1;40;i++)
if LPat[i]=='1' then)
};//end "if/then". No else.
};//end "for.."
^ ^ ^ ^ End of TKB note to self
================================= */

}//end of LiftWarps

boolean boStepSwStateChanged()
//Crude... may need to have debouncing added...

//debug scrap if (digitalRead(swStep)==bStepSwPrevState)
if (bStepSwState()!=bStepSwPrevState)
    return false;
    //Change what's stored for previous state
    if (bStepSwPrevState==0)
    //end of change what's stored for previous state
    return true;
}//end bStepSwStateChanged()

boolean boSwFrmLoomAsserted()
//Possibly wants a debounce... but
//  that can come later. Will need
//  a "previous state" global. Tedious.
//Returns true on negative edge from
//  loom... which occurs when it is
//  ready for pattern to change.
if (digitalRead(swFrmLoom)==HIGH)
     return true;
     return false;
}//end of  boSwFrmLoomAsserted()

void loop()
if (true)//Crude kludge.. now "Continuous-Controlled-By-Loom"
//only. Line was...
//((boStepSwStateChanged()) || (boSetForStepwise()==false))
//...back when the two modes were Stepwise and
//Continuos-Constant-Frequency. When Stepwise re-implemented,
//  introduce the two sorts of "Continuous"

//if (true)//debugging shred

{//Start of "huge 'Do it' block"

//REM may be out of date...
//Then, if in Cont-by-swFrmLoom, do nothing more until a "do it"
//  arrives

while (/*in cont-by-swFrmLoom mode*/true&&boSwFrmLoomAsserted()==false)
  {/*do not much, but wait*/
   delay(10);};//wait for swFrmLoom to be asserted

//{delay(bDelayBetweenMS);};//debugging kludge... REMOVE

//REM may be out of date
//if ((boSetForStepwise())&&({not on swFrmLoom}))
// {delay(bDelayBetweenMS);};//Will be needed even after debugging
//   to moderate "continuous" when s/w added to make using
//   swFrmLoom optional in continuous mode. In other words,
//   there will be three modes: Stepwise, Continuous-by-swFrmLoom,
//   and Continuous-At-Constant-Frequency. This delay will regulate
//   the frequency.

//REM may be out of date
//mostly DONE!... need to add bit to make stepwise operation work
//add delay to give solenoids time to act, warps to settle
//Do throw, if in continous, and a wait, so that next "lift" doesn't
//happen too soon.

//Now... if in Cont-by-FrmLoom, if swFrmLoom asserted, assume it
//   is "tail" of pulse that
//   triggered the current cycle, and...
while (/*in cont-by-swFrmLoom mode*/true&&(boSwFrmLoomAsserted()==true))
  {//do not much, but ...
   delay(10);}//wait of rswFrmLoom to be zero again}

bPat++;//Add 1 to what's in bPat
if (bPat>bLastStepToDo) {bPat=0;};
}//End of "huge 'Do It' block"--------------------------
}//End of loop()

byte bStepSwState()
  if (digitalRead(swStep)==LOW)
    return 0;
    return 1;
 }//end bStepSwState
 //end of program! (^_^)

That's it, for now... and probably for some time to come! Worth what it cost you, if you pay yourself for your time what people pay me for mine.

(Positive) comments welcome, indeed appreciated! Some helpful suggestions were made in a discussion at the Arduino forum in March 2015.

To search THIS site.... (Go to my other sites, below, and use their search buttons if you want to search them.)
Click this to search this site without using forms.

powered by FreeFind
Site search Web search
The search engine merely looks for the words you type, so....
*    Spell them properly.
*    Don't bother with "How do I get rich?" That will merely return pages with "how", "do", "I"....

Please also note that I have two other sites, and that this search will not include them. They have their own search buttons.
My site at Arunet.
My Sheepdog Software pages, another of this page's editor's sites.
Ad from page's editor: Yes.. I do enjoy compiling these things for you... hope they are helpful. However.. this doesn't pay my bills!!! If you find this stuff useful, (and you run an MS-DOS or Windows PC) please visit my freeware and shareware page, download something, and circulate it for me? Links on your page to this page would also be appreciated!
Click here to visit editor's freeware, shareware page.

Here is how you can contact this page's editor. This page, and the software it references, ©TK Boyd, 1/2010.

Valid HTML 4.01 Transitional Page tested for compliance with INDUSTRY (not MS-only) standards, using the free, publicly accessible validator at validator.w3.org