I have now finished the project I started a year ago, after having the summer off, and thought it would be worth sharing my findings with the element14 community who were so helpful at the start.
There are seven main Headings that I want to use in this progress report on "Microcontrollers for dummies" and they are as follows: -
1.The Project
2.Choice of microcontroller
3.Choice of programming language.
4.Dealing with switch bounce
5.Use of interrupts.
6.Pin behaviour at power up
7.The precision clock and the hooter timers
8.What is the yardstick for efficiency of code?
1.The Project - A Portable controller for starting and finishing yacht races and recording individual times.
1.1 The race is started by pressing the control button which starts a 5 minute sequence in which five lights are initially turned on and one light goes out every minute. At minute five and minute four a hooter is sounded for 1 second, but at the three and two there is no sound. At the 1 minute signal a 2 second hooter sound is given, and at the start a 1 second signal is given and the last light will go out.
1.2 As the finishing boats cross the line the control button is pressed which gives a 1 second hooter signal and records the time in seconds from the start of the race for each finisher.
1.3 If an individual recall is needed then a switch is operated after the start and a 1 second hooter signal is given and lights 1 and 2 are flashed simultaneously at 1 second intervals.
1.4 If a general recall is required then one switch is operated and the hooter sounds and then a second switch is operated and the hooter sounds again and the lights 1 2 3 and 4 flash simultaneously at one second intervals.
1.5 If the race officer wishes to impose penalties on to the fleet during the starting sequence, then he has the option of flashing light 1 during the starting sequence to implement the "round the ends" rule. If he wishes to further penalise the fleet then he can implement the "black flag" rule, by flashing lights 1 2 and 3 during the starting sequence.
2.Choice of microcontroller
This comes down to basically deciding how many input and outputs you're likely to need for the project. In this case we have five lights and a hooter and a start/ finish switch and 2 indicator status lights, so it was pretty obvious so we would need in the region of 10 input /outputs on the microcontroller. Also a precision timer facility would be needed, and an EEPROM memory for the storage of the finish times in seconds up to 3 hours. After a couple of false starts I settled for the Microchip 16F630, and all pins are used apart from RA3.
3.Choice of programming language.
As this was my first microcontroller project I decided to have a look at the use of the language C. This appears to be quite a powerful language, but what concerned me was that if I didn't understand what every line of the code did then how would I be able to debug it if there were problems. After looking at the instruction set for the 16F630 then I decided that, by using the various functions such as the "bit tests and skip” commands, then I could quite easily simulate the "if then” programming function used in C. Also the rotate left and right commands gave the means to alter a register progressively in an interrupt sequence, so that one could step through the 5 minute sequence using one piece of interrupt code. It was slow writing in assembly, but I knew exactly what every line was for, and was able to debug confidently.
4.Dealing with switch bounce
There were quite a few clever bits of programming given in the various tutorials which were designed to eliminate problems caused by switch bounce. I found these a bit convoluted and difficult to understand. What I found to be more effective was to use the switch to start the interrupt, and then not to reset the flag. If it was necessary to have the interrupt functioning again, then it was easy to put in a time delay after the interrupt which covered the time of the switch bounce. I was using a micro switch and am I had a look on the oscilloscope at the bounce, and this was never a longer than 5 milliseconds. So what I did was to put in a 20 ms delay loop immediately after interrupt before resetting the interrupt. This worked reliably and consistently.
5.Use of interrupts.
I tried to use the interrupt on change facility which is available on some of the ports but found that this was quite difficult to use consistently. So much depended on what the ports had been used for prior to the interrupt and in the end I gave this up and settled for the RA2 port which has a special interrupt facility. The Timer 1 interrupt was used to set the 1 minute intervals by preloading the timer registers and this worked reliably.
6.Pin behaviour at power up
I found that the behaviour of the RA pins on this microcontroller was quite erratic on start up. For example, before these ports settled at their proper programmed values, then they could give outputs lasting several milliseconds. This meant that any device connected to them could be triggered on switch on. This was not the case at with the RC pins, however. I guess it is something to do with the multiple functions of the RA pins.
7.The precision clock and the hooter timers
I was advised at first to use a discrete crystal to build a precision timer but I found that the stray capacitance affected the operation so much that it was not possible to build a reliable circuit. What I did find was an integrated circuit was available which contained a precision oscillator and I used that in the end and have achieved good reliable results. The oscillator is used to feed 2 counters in tandem and this gives me the required precision. The system has a resolution of one second and is very accurate. The hooter timers were developed using simple stand alone 555 circuits as it was not possible to use the microcontroller without affecting the timing accuracy of the system.
8.What is the yardstick for efficiency of code?
I would be interested to hear from any readers of what they think is efficient code. In this case I have achieved the above using 188 lines of code but am at a loss as to know whether this is efficient or not. Does anyone have any comments on that?