This isn't so much an update as it is both a lesson, and a reminder.
Tonight I let the smoke out of a PIC16F876, and a 20x4 LCD. Not a bad evenings work :/
Here's a little back date on how I arrived at this moment:
After a little deliberation, and just slightly more frustration, I decided to drop MikroBasic for the remainder of the project. While the floating point would be useful, and the IDE is really very nice, I was unable to come up with a suitable solution to send long text strings to the serial port. PicBasic Pro does everything I need, and I'm familiar with it, so I'm forging ahead in a comfortable environment.
An important lesson I learnt a long time ago is that you should do as much in the simulator as you can before committing your time to a physical model. I was so keen to start doing tests on a live model (reading battery voltages and beginning actual research) that I failed to test my code in the simulator first. If I had done so, I may have saved myself the pain of losing a treasured 20x4 LCD. More on that in a moment.
Before the loss of the LCD, came the loss of one of only three PIC16F876's that I have on hand. This was purely due to lack of concentration. I managed to swap the Vss and Vdd pins on the power rails when I set up the breadboard. Avoid this at all costs.
So I found my error, corrected it, double checked the remaining wiring, and programmed up a new 16F876 with my test code. If you've been following the design process so far you may have observed that I originally used a 16x2 LCD in the design. On the spur of the moment I decided to upgrade to a larger display so that more information could be displayed in a single viewing. I wrote the new test code in PicBasic Pro 2.60 and completely failed to try it in the simulator. The LCD simply wasn't behaving the way I was expecting it to. I recalled having seen this type of behaviour before and foolishly though it was a case of the circuit being underpowered. I built a regulated 5V rail for the micro-controller to be fed from to allow me to increase the voltage slightly being fed to the LCD from an alternative rail. This didn't solve the problem at all. Unfortunately, my ageing LCD didn't have the tolerance for the extra few volts resulting in a now dead display. I took my code into the simulator and was very surprised to see it reacting EXACTLY the same as it did on the live model. It actually appeared as if the LCD wasn't synchronising. I'd already factored in a 1 second delay to give the LCD time to initialise but that didn't fix it. Then it struck me. I was using a 20MHz oscillator, but I hadn't defined that in the code. The processor would be trying to execute at the default 4MHz giving unpredictable results. One line of code later, and a switch back to a 16x2 LCD, and the live model was up and working.
While I don't think the simulator would have saved me from the carelessness of swapping the power connections, I think it would have saved the LCD from its untimely demise; this time.
Rather than go back and edit the previous part, I'll post the new code and test results in the next entry.
With the basic modules designed, and put in place, it's time to begin testing each section before continuing any further.
Project X: The Intelligent Battery Charging Station - Part 3a
Before pulling out the breadboards to build the prototype circuit, I like to test the build in a simulated environment first. Proteus is an excellent tool that has some incredible features to help make prototyping as streamlined as possible.
I've chosen to use MikroBasic Pro for the uC firmware. The main advantage here, over say PicBasic Pro, is the way it handles floating point maths, and strings. While I still haven't researched, or even really thought out, the charging/discharging principles, I think it's a fairly safe bet to say that we'll be dealing with more than just integers. Since I've hardly done anything with MikroBasic before, it will be important to test each module in the circuit individually while I get used to the new language properties. The display is an incredibly powerful tool in our arsenal since we can use it to display debugging information. For that reason alone I will tackle the display module first and work on getting some reasonable results.
I just noticed that I never finished the .NET project from 2008. Since the Project X dealio will be communicating via RS232 and the interface will be displaying graphed data, it's fair to say that this can act as a continuation/replacement of the former project.
I haven't started my research just yet. Instead, I decided to work out the easy stuff first and get that up here, out of the way.
Project X: The Intelligent Battery Charging Station - Part 1
The project is pretty simple in an overall way. Like most of my projects, the design can be broken up into fairly portable modules. By tackling the project this way, it's pretty easy to get a pin count and start working out what sort of micro-controller needs to be employed.
Modules:
Power State -
LEDPOWER is controllable through PORTB.0 and is planned to indicate that code is running, not that a supply voltage is present.
I think it's time to dust things off here and start a new project. Who's with me? It's hard to believe it was 2008 since I last updated. Sad, but true. It's also hard to believe that it's also how long it is since I've pursued this hobby. Hopefully things haven't changed too much since I last did this ;)
Project X: The Intelligent Battery Charging Station - Part 1
Preamble: We use a lot of rechargeable batteries in our household. The majority are AA's that get used in the toys for the kids, and we also have a handful of AAA's that get used in remote controls and what not. I have a bad habit of forgetting to check on the recharging process of the batteries. It doesn't take long for the batteries to deplete if I don't remember to take them from the charger once the process has completed.Additionally, we have a baby monitor that has a built in charging stand that tends to reduce the life expectancy of the batteries in the monitor.
The cheap battery charging stations we have don't do a great job of charging. They're very slow, don't alert me when the job is done, don't discharge the batteries very well (that I can tell) and have no means to tell me the condition of the batteries being charged. These all sound like good reasons to build my own charging station.
Proposal: To increase security and reduce long term costs of key and lock replacement on the CCAN site. This can be achieved using a low cost RFID solution.
Outline: There are two possible solutions being outlined here. Pros and Cons will be evaluated in time.
Solution 1: External RFID reader is connected to a microcontroller that passes data via RS232 to a stand alone server. The server is responsible for validating the data and time of day against an employee database. It also logs all activity. Externally, the software is accessible across the network and the log capable of being displayed through web based software. Limited control and diagnostics can also be performed through this interface. Remote diagnostics and control would primarily be undertaken through a VPN. The controller is responsible for triggering the door latch, reading the door status and passing this information through to the alarm controller. It needs to give feedback through LEDs, and a buzzer. It also need to allow the door to be unlatched via a button inside the building.
Solution 2: External RFID reader is connected to a stand alone microcontroller controlled device. This device stores a database of employee information in flash ram, requiring no control from a PC for day to day activity. A connection via RS485 to a host PC allows the database to be updated and logging data recorded. Otherwise, the controller boasts the same features and task requirements as Solution 1. The part count and development time are higher for this model.
This project will be quite sizable in it's design. To better facilitate that process, it will be broken down into a number of smaller sub-projects. Those smaller projects will encompass even smaller projects that have already been tackled, or will be done on a need to do basis as they are called for.
Speed/Voltage comparator: The completed project will need to be able to control a locomotive at varying speeds over a test track to build a voltage/speed control table. To do this, track voltage would need be monitored while the locomotive is timed passing between two points. Using the formula Speed = Distance / Time we can then calculate the actual speed the train is moving. From there it is a simple step to further calculate scale speed. Armed with this information, it will be possible to limit the voltage to the rails in order to limit a locomotive to a maximum speed.
My initial thoughts were to make a long straight section of track with graduated markers along the side. I decided that a simpler approach would be to make an oval with a smaller sample area. Obviously the larger the sample area, the more accurate the data. For initial tests though, a small sample should suffice.
At first I'd envisaged using an infrared LED and receiver to detect when the train first passed. A timer would start and continue to run until a second iR beam was broken, a set distance away. This would require a 38Khz PWM signal to drive the iR LED, some filtering circuitry to increase the accuracy of the readings and lessen the chance of the receiver being triggered accidentally by natural of fluorescent lighting, and a lot more code than I was prepared to write. I decided to try a simpler approach using an Orange LED and an LDR. I just needed a way of mounting them accurately at a fixed distance with no chance of them moving ...
... never ever, ever, ever throw away your old Lego :D
I finally got around to making some changes to my code. I'd been thinking about this for the last week but have been too busy to do anything about it. I had a small window of opportunity this afternoon so I pounced ;)
Basically the code uses a new scaling routine to limit the range being output from a potentiometer between 0 and 255. Two buttons are connected using the same method from my earlier button test project. Button 1 allows the code to enter a calibration mode. Button two is used to select the point when the pot is at the minimum and maximum limits. The scaling factor is then employed and the result displayed.
To do my PIC16F628 tests, I decided to do a fresh start on a different breadboard. This effectively means I can show you the process to get started, blow by blow. You can follow this guide using your PIC16F84A with no problems. You'll just have to make a small change to the code later on.
Component List: 1 x PIC16F628A 1 x 20MHz Crystal 2 x 22pF Ceramic Capacitors 1 x 0.1uF Mono Capacitor 1 x 5mm LED 1 x 470R Resistor 1 x 4K7 Resisitor
That last post made me go out and inventory what chips I actually do have. I'm only listing the stuff from www.microchip.com. I'll do the Dallas stuff later since a lot of them are surface mount and will require a lot more attention to document ...
I just received another new order from Microchip.com. I'll link the data files later, but for now, the list is as follows:
MCP41010 ENC28J60 PIC12F683 PIC12F510
All came as DIP packages for easier prototyping. Yay! I can't recall the features of these chips, but one of them will allow me to create networkable hardware. That's really going to open things up!
I took the revised code from the PotTest project and added another line of code. I wanted to see what would happen to the LED output if I slowed the main loop down a LOT. I put a Pause 200 in just before the return loop (Goto Start) and observed a blinking LED. Okay, so the PWM command does not background task. A little further research now has me looking at the HPWM command. It's supposed to be completely background independent but requires compatible chips. Here's where things got real interesting ...
It turns out that the PIC16F628 is pin for pin compatible with the 16F84. It has a slew of extra features, extra memory, and is actually CHEAPER than the 16F84. It also has hardware PWM and an onboard oscillator! At start up the PORTA pins are configured as comparators, so we need to add an extra line of code at the start of our programmes if we want to use PORTA as a normal I/O arrangement. Simply use:
CMCON = 7
This will configure PORTA as all I/O pins.
I have a few of these chips already so I'll start running some tests tonight hopefully. I noticed the 16F648 is the same again with even more memory (4K?) ... I don't know if I have any of these though.
Looking closer at the pot test project, I may have come up with a solution to getting better results without actually changing the circuit. Since the 16F84 has no floating point math, we can't use a simple pre-scaler to adjust the results. For example, in a floating point environment, we would simply say maxPot_value / maxIdeal_value = preScaler; or 635 / 255 = 2.49. We'd then divide whatever value we read from the pot with the pre-scaler to get an ideal value in the 0-255 range. So a reading of 462 on the pot would translate as 462 / 2.49 = 185.5. With no floating point math though we have to do things a little differently ...
If we multiply everything by 10 and do the calculations again, it would look like this:
6350 / 255 = 24.9 ... without the floating point, it would become 25. Our pre-scaler is now set to 25. Our reading of 462 would now be multiplied by 10 to get 4620 and that can be divided by our new pre-scaler to achieve a result of 184.8 which will round up to 185. Problem one solved. Now there is just the question of the lower limit. I could always just subtract 1 from the initial pot value ( 0 - 634 instead. )
That would then be 634*10/255 = 24.86 and thus still work perfectly ...
potValue VAR WORD preScaler VAR BYTE scaleValue VAR BYTE maxPot VAR WORD minPot VAR WORD
... Do calibration routine here to obtain maxPot (high) and minPot (low) pot values by winding the pot through it's limits ...
I'll do some tests with this through the week. The next step will be to get two pots working. They can then be used simultaneously to adjust both variables in real time for the PWM command.
I've been really slack and unmotivated of late. Most of that has been because of my workspace. I had planned on getting the garage sorted out on Father's Day, but the weather prevented that from happening. There was just too much wind and rain to be able to move things outside to sort through it all.
Yesterday I woke up early and had a bug up my ass. I set to work and cleared out the garage and made myself a workshop. I did a little cleaning in there today and I'm really happy with the results. So much so that I even got a small project out of the way when I finished! I only wish I had another day off work now to get in and do some more :/
The pot test uses the RCtime command to read the pot by checking the discharge time of a capacitor in circuit. The schematic, minus the standard 16F84 circuit with power LED and LCD, follows:
Here's the PicBasic Pro code to accompany the circuit. I really hate that my tabs get all messed up but I couldn't be fucked fixing it for here. It displays the way I want it to in CodeDesigner ...
The value returned for my 10K pot was between 1 and 635. For real world applications I'd prefer a value between 0 and 255 (8 bits.) The # in the LCDout command converts the VAR to an ASCII string.
I did a second version of the code that uses PWM to vary the intensity of the power LED. To get the pot value back into a range from 1 to 255, I simply divided the value by 3. That gave me a range of 1 to 212 (212 being the brightest.) The revised code is here.
I'm not totally satisfied with this method, but it got a fast result. I'll tune it up later and do some tests with different value capacitors. The 0.1uF one I used here was one of those blue mono types that we have millions of. Nice to know that it can be used for fast user feedback ;)
Get a 10K pot working. If the POT command doesn't give satisfactory results, look at the RCTIME command that was used in an earlier experiment. M_xxx code.
Write code to get a second pot working simultaneously, outputting scale data to the LCD.
Check out HPWM command and what chips it can be used with.
Use PWM to drive a simple H-Bridge circuit with a linear voltage range and fixed pulse timing.
Use the two pot code to adjust the on and off pulse timing using a motor and flywheel to gauge the noise/efficiency. Watch motor for heating issues that may arise.
I just received a partial order shipment from Dallas/Maxim. I didn't get everything I ordered though despite them saying they were available as samples :/
Man, I really wanted the DS2422S+. Oh well. I think I might try to order them again anyway and see what happens ... I also want some stand alone real time clocks, so that will be enough to fill an order soon :)
I'm making a series of "base" microcontroller footprints for use with Visio. The footprints will have the base component and wiring needed to get the chip going. The first one is for the PIC16F84A
I measured out the front panel and then drew up a rough layout of how I wanted all the components arranged. After swapping things around a few times until it made for a better layout, I began working things into a geometric design so that the final interface would be both functional, and pleasing to look at. I then calculated out the spacing, checked my dimensions, then scored the face of the panel to represent the centres of everything that was to be mounted. Unfortunately I did something wrong with the camera, and the photos I took of the initial construction have been lost :( Holes were drilled one at a time, and each component test fitted before continuing on to the next. Once done, it was time to design the artwork for the front panel.
The artwork was done using Adobe Photoshop CS2. It's a fast and easy way to get professional looking results, even from a simple home workshop.
While I was in the shower this morning I got to thinking about the PSU design. I decided that because the switches I had already bought to control the output were SPDT, I could connect a second LED to the "OFF" side and indicate positively that there is no power being output. That way if the "ON" LED should fail and I happened to miss the switch position, there would be less likelyhood of me destroying the programmer by having power to it and the circuit at the same time. Also, a little more research came up with a better design including flyback diodes and different capacitor values. With the two PSU's now having an off status, the "Power" LED became redundant. I might add a neon indicator directly across the mains switch later if I think it is warranted.
I didn't get as much done as I wanted to, but I did manage to get the circuit diagram done for the PSU portion of it. I need to map out an idea I have for an LED to indicate what mode the box is running in, ie. programming / code running that I will work on and add to the schematic.
Tomorrow I will try to build a prototype on the breadboard before committing to the final design and build. Then I just have to work out the component spacings for the front panel, measure, drill and assemble the face, build the protopcb and wire it all together. I'll do a nice label for the front panel too. I'll print that on photo quality paper, clear contact it, then use adhesive to stick it to the font panel before mounting the LED's and switches. That should make it look pretty cool.
Switchable In Circuit Serial Programmer - Upgrading the ICSP adaptor.
Part One:
The idea is simple enough. Put a switch in a box and connect it in such a way so that it does the same job as plugging the ICSP adaptor in and out of the programmer, but without the fuss.
Components: 1 x Jiffy Box 1 x 4PDT Switch 1 x 10 Pin female DIL IDC ribbon cable connector 1 length of 10 way IDC cable The original ISCP adaptor
Your work area is set up. You've followed the last post through to make your ICSP adaptor. You've read both parts of the LED tutorial and now you're ready to make it all work :)
We're going to play with some LED's now. They're a great way to get into the swing of this whole microcontroller business.
Materials: 1 x PIC16F84A 1 x Crystal (4~20MHz) 2 x 15~33pF Ceramic Capacitors. What ever you choose, just make sure they are both the same. 1 x 0.1uF Capacitor (one of those little blue mono types is fine) 1 x 4K7 Resistor 8 x 5mm LEDs (your choice of colours) 8 x 220R Resistors Jumper wire for your breadboard
Schematic:
Construction: Build project on breadboard as per schematic. Try to line your LEDs up in a row with even spacing between them. Keep the 22pF caps as close to the crystal as possible. Double check EVERYTHING!
Code:
DEFINE OSC 4 ' Set up timing to match the 4Mhz crystal
x VAR BYTE ' Declare a variable named "x"
Start:
Pause 500 ' Wait 500 milliseconds before continuing code execution
High PORTB.0 ' Set pin RB0 to HIGH (+5V). This will be the power indicator to show the code is running
Pause 1000 ' Wait another second before continuing.
For x = 1 TO 7 ' Loop 7 times, once for each LED in our chain
High PORTB.x ' Turn each LED on in turn
Pause 150 ' Leaving it on for 150 milliseconds
Low PORTB.x ' Then turning it off before looping with almost no delay before the next one is lit
Next
GoTo Start ' Do it forever
Use CodeDesigner Lite to enter the code above and save it with a .pbp extension in the folder where your PicBasic Pro executable is. Compile the code by pressing F5. You'll now have a .hex file in the same directory that can be loaded into your programmer. Make sure you use the XT setting for a 4MHz crystal, and the HS setting for anything faster. Check, double check, and then check again ... Breadboard power is OFF. ICSP adaptor is plugged in. Programme the chip. Disconnect the adaptor. Check your wiring again. Fire up the breadboard. The power LED should come on after a short delay, then the other LEDs should start chasing each other.
Construction of an ICSP is pretty straight forwards.
Material list: 1 x 18 Pin DIP socket 1 x 5 Pin SIL strip 5 lengths of different coloured hookup wire Cable ties Some 1.5mm heat shrink tubing
Connections: There are 5 pins we use to programme the 16F84A. Vss, Vdd, Vpp (MCLR), RB6 and RB7.
Construction: = READ ALL INSTRUCTIONS FIRST = 1. Trim the 5 lengths of hookup wire so that they are all the same length. You should try to keep them as short as is practical. Don't make a 1 metre long adaptor, okay? 2. Strip a couple of mm of the ends of each wire, twist the braiding and then tin each end in turn. 3. Orientate the DIP socket and identify each pin you will be connecting to. There will be a wire soldered to pins 4, 5, 12, 13, and 14. 4. Solder each wire to the top of each socket carefully. Don't over-heat the pins or the legs will distort. 5. Cut 5 x 6mm lengths of heatshrink tubing and slide one onto each of the wires. If you need them where you've just soldered then slide them into position and heat them with a heat gun or hair-drier to set them in place. Make 5 more 6mm lengths if you used the first five and slide one more onto each wire. 6. Insert the 5 pin SIL into your breadboard so that the short legs are facing up. Tin each leg carefully using as little solder as you can. Be quick - the base will melt easily and deform the legs. 7. Solder each wire to a different pin. There's no order to follow although I did mine 1. Vpp, 2. Vdd, 3. Vss, 4. RB6, 5. RB7 8. Slide each heatshring tubing sleeve over your soldered pin and then heat again to set in place. 9. Cable tie the wires together in a few places to make a tidy loom. 10. Use your meter to ensure none of the pins are shorting with anything they're not supposed to be.
Usage: Insert the SIL into a convenient place on your breadboard that is reasonably close to your PIC. Run a jumper from each pin of the SIL to the appropriate pin on the PIC, ie: Vpp to Pin 4, Vss to Pin 5 etc. Always remember to turn the power off to your breadboard BEFORE inserting the programming adaptor into your programmer. The adaptor will power up the chip for programming. With the adaptor in place, use your programmer software to programme the PIC with a compiled HEX file. When it is complete, remove the adaptor from the programmer but leave it plugged into the breadboard. Powering up your breadboard should start the PIC running. Any other type of PIC you choose to use will only need to have the jumper wires changed to the approriate pins on the PIC, not on the SIL or adaptor DIP.
I'll be making a version of this soon that will remain permanently connected to the breadboard and programmer via a 4PDT switch mounted in a jiffy box. I'll document the project from start to finish with photos and constrution notes in ase you want to emulate it yourself. This will probably be done on the weekend along with a couple of other small test projects I want to build. Watch for the design notes here :)
There's a whole bunch of ways we can hook up an LED in a circuit to be controlled by a microcontroller (uC.) The simplest way is by connecting the LED directly to one of the I/O pins of the uC. This in itself has two choices. We can either connect the LED to VDD and sink the current to turn the LED on when we turn the uC pin goes LOW, or we can connect the LED to VSS and source the current to turn the LED on by sending the uC pin HIGH. Either way, we need to know about the characteristics of LEDs so that we can make some neccessary descisions.
LEDs An LED will light only when current (i) passes through the diode in a forward direction. The current must be propelled with a forward voltage (VF, or VFORWARD) that is greater than the barrier voltage of the diode. When the barrier voltage is exceeded, the diode begins to conduct current very well. Too much current will cause the LED to expire permanently. For this reason, we need to limit the current with a resistor.
For this project we'll be powering the LED by sending the uC pin HIGH. A HIGH port pin on a PIC16F84A is 5 volts. A good rule of thumb is that an LED will have a voltage drop of about 1.4 volts across it and a maximum forward current of 20mA. Using Ohm's law we see the following:
R = V / I
R = (5V - 1.4V) / 0.02A
R = 3.6V / 0.02A
R = 180 Ohms
This represents the MINIMUM value we should use. Using a slightly higher value will further reduce the current passing through the LED and therefore cause it to dim proportionally to the value used. Good results can still be obtained by using a value between 220 and 330 Ohms with little worry that you will damage the LED or the uC pin.
When starting out with microcontrollers, there's a distinct desire to see something working early on. Probably the easiest thing to do to satisfy this desire is to turn an LED on. It soon becomes apparent that it won't be all that hard to go one step further an make it flash on and off.
While only a simple project in itself, there are design considerations to be made. It may seem trivial but later on in the larger projects everything that we learn now will be revisited.
This project will attempt to use a microcontroller (uC) to repeatedly turn a 5mm red LED on for half a second, then off for a half a second. While overkill for this project, a PIC16F84A running at 20Mhz will be used due to ready availability and cheap cost. It will also allow expandability in the next few experiments. The uC will be programmed using melabs USB programmer and PicBasic Pro version 2.46a.
Because I have so many real world projects in mind that require talking to an actual PC, there has to be a way to share data back and forth from the microcontroller hardware to a PC. I made a quick interface using a MAX232E chip wiring it as per maxim's instructions and connecting it to pins 2,3 and 5 of COM1.
Tonight I built a button interface as a module. It took maybe an hour from start to finish including design, construction and writing some really poor code to test it out.