Sounds good… last thing I want to point out is that the accelerometer presents a continuously changing analog signal that can be read as quickly as you like. The PIC’s A2D will be the speed limiter here.
Speaking of ordering parts…
I figured that I’d run my current parts list by you guys in case you see something wrong with it:
Jameco
(1) Schwab’s 3lb. Grab Bag- Pot, LED, Res, Cap, etc. (163213) *
(1) Heat Shrink Tubing 1/4" x 4’ (419207) **
(1) Heat Shrink Tubing 3/8" x 4’ (419223) **
(1) Heat Shrink Tubing 1/2" x 4’ (419240) **
(100) Female Pin Crimps .1" (100765)
(1) Rectangular 36 Crimp Pin Housing .1" (103157)
(10) Male 8 Pin Header .1" (153701)
(1) Crimper Tool For 100765 (99443)
Microchip
(2) PIC18F4620-I/P
ServoCity
(1) Servo Wire 50 ft. 22 AWG (57417) ***
eXtreme-DIY
(1) ADXL32x Breakout Board 2g
SparkFun
(1) Black Hook-up Wire
(4) Metal Hex Standoffs 4-pack ****
(1) BlueSMiRF Bluetooth Modem
(1) Bluetooth v1.2 USB Dongle
- Anyone know if this is a decent kit?
** The heat shrink tubing is to encase the entirety of the biped’s servo cables, once I replace them. I’ve gotten frustrated with the tied-downs getting caught on things, so I figured a lot of shrink would look better and be more functional.
*** I couldn’t find any 20-22 AWG ribbon wire from Jameco, so I have to buy the way over-priced stuff from here. Am I just looking in the wrong place?
**** This should solve my only quandry with Jim’s products: the nylon hex standoffs. Jim’s work great if you don’t ruthlessly take them appart and put them back together frequently. But I find myself continually stripping them on my biped’s backpack, since I keep needing to take it appart to get to things.
I’ll take that as a “go ahead, Nick”, hehe.
I’m adding a couple things onto that list:
Microchip
(2) MCP3208-CI/P (12-bit 8-channel A/D converter)
Sparkfun
(1) USB Cable A to B - 6 Foot
(1) MPLAB Compatible ZIF Programmer - USB Powered
(2) DIP Sockets - Solder Tail 16 Pin
Jameco
(3) IC,NTE960,VOLTAGE REGULATOR +5V,1A,TO-220 (260259)
(1) BAT HOLDER,2-AA,WIRES W/COVER & SWITCH (216119PS)
(3) BAT HOLDER,2-AA,WIRES,COVER W/COVER, (216101PS)
(3) BAT HOLDER,2-AA,WIRES,TABS W/MOUNTING TABS (216098PS)
(2) PROTO BOARD (.1" tin pads plated through)
And I’m getting power connectors from LM (as well as a bunch of SES brackets and a bigger waist rotate servo).
I’m buying the A/D converters for ■■■■■ and giggles, now.
Perhaps I’ll use them for the pressure sensors, later on.
But, for now, I’ll be focusing on the accelerometer, as I don’t have a good foot design that works well with the pressure sensors.
You’ll notice that I finally broke down and got a MPLAB compatible programmer.
It’s a bit on the expensive side, compared to others, but I didn’t want to get discouraged by having software that didn’t intuitively work together.
Plus, it’s the only one that doesn’t disclaim that my laptop’s USB port may not be able to power it.
I’m getting all of those battery holders because of my previous battery problems.
They’re cheap, so I bought a couple types to see which will work best for me.
Sigh… here goes $400 more into my biped.
Hopefully, I’ve got enough extras of everything that a little bit of magic smoke won’t halt my progress for the week or so that it takes to order another.
If nothing goes wrong (yea, right!) I’ll have enough parts to build two full boards and still have quite a few extras.
I can’t wait!
::hops up and down in excitement::
Now I’ll actually be able to get into the nitty gritty of electronics that I’ve been reading up on, instead of being a passive “oh, so the manual says you connect this here, eh?” kind of guy.
Wish me luck!
Nick,
I jump up and down with my knees bent, and my feet pointing out in excitment for you!
Go Nick go!
Nick, learn to love manufacturer’s samples.
Heh.
I always do.
By the way…
I didn’t like the look of that VRM from Jameco, so I’m getting the 500mA 5V one from LM, instead.
I think the other one required a really high input voltage.
And, Dan (the head of CJRG and SJRG) called me from Cali, today and he recommended that I save myself some coin and go with the Tiny-ICD2 programmer from SparkFun.
Since the supply is seperate from the USB port, my laptop should work fine with it (provided the DB9->USB cable works with it).
If not, I’ll just use it on my old desktop.
A question for the gurus…
I’ve seen quite a few different setups with voltage regulators.
The question is, though… which do you guys think is best when supplying a microcontroller?
homepages.which.net/~paul.hills/ … age115.gif
I’ve seen the one above repeatedly.
In my Digital Electronics Demistyfied book, it says that C1 should be a 10uF cap and C2 should be a .1uF cap.
Supposedly, C1 dampens the spikes from the power source and C2 provides the logic portion with the ability to demand power quicker than the VRM can actually supply.
Are their better setups than this?
Nick this is the design that I am using for my RSCU board. I found this example on the web and unfortunately I don’t remember the link. It’s supposed to provide over volt protection. I have had no problems what so ever supplying 7.5v to 16v and its rock solid.
Nick,
The values you mention should be fine. Mike’s values are ‘overkill’, but it does no harm other than perhaps raising the price a tad.
The large input cap (100 uF) is not really ‘overvoltage protection’, although it will very briefly protect the 7805 from a very high input voltage (higher than the roughly 30V that it’s rated for).
The more important function of C2 is that it prevents oscillation of the regulator.
The 7805 is a “classic” for 5V regulator chips. If you don’t mind spending an extra 50 cents or so, you could go with a “low-dropout” regulator (LDO). An example is the LM2940 (there are many others). It works just like the 7805, but will put out 5V when the input is only 6V or less, whereas the 7805 requires at least 7V input to put out 5V.
With any of these regulators, be aware that to put out the rated current (i.e. 1 amp), you’ll need a heat sink. The higher your input voltage is, the bigger the heat sink needs to be. Fortunately, most of the electronics we’re talking about uses very small currents, so little or no heat sink is needed.
Pete
Nick: Regarding the “Tiny ICD 2”:
It’s serial only. Weren’t you trying to go USB?
Pete
My mistake, the circuit I used has overload and thermal protection, and not over volt like I thought (bad memory ). I found the website that I got the 5v regulator circuit from.
Umm… isn’t the 5V 500mA from Lynxmotion an LDO?
It says so on the site.
Ahhh…
So, if the regulator was oscillated, it would make a messy sort of high-speed PWM on the power rails?
Yuck!
Yep, you’re right.
I was.
But then Dan called and reminded me that if my USB->Serial cable didn’t work with my laptop, that I had a desktop with free serial ports to fall back on.
He’s also used this bugger and is a local guy (when he’s not in Cali >.<) that I can run to quickly if (read: when) I screw something up.
Yes, it is - my fault - I thought we were talking about the 7805, as shown in the image that Mike had posted.
Pete
No worries.
^.^
I’ve been reading a bunch of books, as well as the .pdf for the C18 compiler and the .pdf for my microcontroller as well as collecting example code from the web.
I tried playing with the compiler a bit and making my own test programs so I’ll be ready to go when the micro comes.
This is the one I’m working on, now:
[code]#include <PIC18F4620.h>
void main (void)
{
TRISA = 0; // Make all of the port’s pins outputs.
int i;
while (i < 20)
{
i++;
PORTA = 0; // Set all of the port’s pins low.
delay(); // Pause to make the change visible.
PORTA = 1; // Set all of the port’s pins high.
delay(); // Pause to make the change visible.
}
}
void delay (void)
{
int j;
for(j = 0; j < 200000; j++); // Ties up the processor for a bit.
}[/code]
Right now, it’s just a simple light blinker (woopdiedoo! ).
As long as I’ve got an LED in line with a 470 ohm resistor on one of PORTA’s pins, I’ll get my desired light show.
However, I don’t wish to do the above.
All the examples that I’ve seen show the PORT example because it works on every microcontroller and is pretty foolproof, since it’s hard to put an LED on an entirely wrong port.
I wish to specify exactly one pin to set as an output and then turn on and off.
I’m guessing that the way to do this lies in this part of the User’s Manual:
I’m guessing that the above table is supposed to tell me the registry address of the pin that I want to specify.
However, I don’t know the format of using that address to ennact changes upon that pin (or if the address is even needed to do that).
Can someone point out the obvious for me?
Oh, and another thing…
I’ve seen
while (1)
{
...
}
in quite a lot of examples.
Exactly what does this mean?
I understand that
while (<CONDITION>)
{
...
}
is just the C equivalent of the Basic
Do While <CONDITION>
...
Loop
But, in the “while (1)” example, the is an integer.
This has me befuddled.
Does it just literally mean “do the following code for one iteration”?
while(1)
means loop forever (in C if you evaluate an int, any non-zero value is considered true). Programs that run on the PIC don’t exit the same way a program might on Windows. It is the entire codebase so there’s no operating system to return to. If your program on a PIC ends, the chip enters sleep mode, as it will with your LED sample there.
To toggle just the pin you’re interested in, read up on bit masking.
Your delay is no where near as long as you think it is. Assuming that compiles down to 3 instructions, that’s only 3.7ms if you’re running at 32mhz. You won’t be able to see if flashing that quickly.
I’m uncertain of the “ideal” way to do delays with C18… I’m used to CCS giving me nice delay_ms() and delay_us() functions based on my clock speed. Pete can probably jump in there.
Ahhh!
The while(1) thinger makes sense, now.
Especially because I saw it in so many programs.
I’ll multiply that delay by 20.
I’m betting that number (which I got from a Microchip example program) is for a micro that’s rather slow.
Is there any way to put the micro to sleep and then have the code wake it up again (like the system.threading.thread.sleep(ms) that you tought me for VBE)?
Having it think away all the time seems a bit wasteful.
Nick, (sorry if I cover stuff you already know) if you have a look at Table 5-1, p62 of the PIC18F4620 datasheet it shows the register map for the chip, on the bottom right it shows PORTA’s address as F80h. F80h (h denoting it as a hex value) is the register’s physical addess in the chip. To save you having to remember that this number is the address of the pins on port A, they assign a label PORTA. Notice that at the beginning of your code you have an include statement for the PIC18F4620 header file
you’ll find it contains all the standard labels for the register locations in the chip (the file should be located somewhere in the installation path of the compiler/IDE) and luckily these labels are the same (or at least they should be) as those shown in table 5-1.
I’m not sure, but there may also be a bit mask specified in the header too, other wise you can create your own:
or something to that effect (sorry, my coding’s a bit rusty, it’s been a while ). Then using bitwise operators as Andy mentioned (sorry, can’t remember the correct syntax)
you can turn on and off specific bits on a particular port/register.
For delays, if you don’t want to tie up the processor in a loop to produce a delay, have a look at using interrupts and the timer module.
Hope at least some of what I’ve typed makes sense…
Cheers,
Chris
I just noticed in your code, I think TRISB should be TRISA since you’re working with PORTA?
I’ve never used C18, and I’ve just started using C30. My experience is all with PICC, but hopefully it’s pretty much the same:
Here’s some notes:
- In your code, you’re setting port B to all outputs, but then you’re writing to port A. If you’re using port A, change the 1st line to TRISA=0.
- You should assign an initial value to variable ‘i’. I’m sure it will default to 0 as you intend, but it’s a bad habit to not init stuff.
- Be aware that the ‘int’ type is (I think) compiler-dependent as to how many bits it is. In my own code, I have type declarations for types of integers that I use, such as tiny (a signed byte), utiny (unsigned byte), short (signed 16-bit word), etc. The reason I mention all this is because in your delay() function, you may want to make the for-loop much longer as Andy pointed out, but if you make it too big it exceeds the size, which in this case might be only a 16-bit value(?), which would limit you to 32767. So you might need a ‘long’ type.
- Depending on what’s in the PIC18F4620.h file, you should be able to change lines like “PORTA=0” to “RA0=0” and so on. The compiler should do the right thing to make it “put a 0 on pin RA0 and leave the other pins alone”. [Hint: Be careful about trying to do things like RA0=!RA0 – it may not do what you expect.]
- Delays: I’ve used some pre-written code like what Andy mentions. It takes into account the clock speed, etc. It’s a good simple way to get going, but I don’t recommend it as you get more advanced. Those delay macros have to know things like how many clock cycles does a given instruction require, etc. So if you change to a different PIC, you may need to fix the delay routines. I do all my timing with timer-based interrupts. Once you understand how to do it, it’s easy to copy-and-paste the same code to other apps and other PICs. And it has the BIG advantage that the CPU is not tied up while you’re waiting.
- Yes, I believe it’s easy to use timers, interrupts, and sleep-mode to do what you suggest (go to sleep, and wake up when the timer expires, do some work, then go back to sleep). I haven’t ever used sleep-mode yet, but the details are in the PIC’s datasheet. I think that some peripherals keep running during sleep (hopefully timers do).
Pete
Nick,
Here’s a code example for doing timing with interrupts. This example is for a 16F88, running at 8 Mhz from it’s internal oscillator. I stripped out everything that wasn’t essential for the example.
TMR0 is mostly for shorter timings - some of the other timers are better at doing longer times. The values 7812 and 156 are “rough”.
#define SECOND_TICKS 7812 // # of interrupt ticks in 1 second w/ 8 MHz clk
#define MS20_TICKS 156 // * of interrupt ticks in 20 mS, for 50 Hz servos
void main(void)
{
second_tick = 0;
seconds = 0;
// Setup timers.
OPTION = 0b00011111;
TMR0 = 0x66; // set the timer period for 128 uS interrupts
PIR1 = 0; // clear flags
INTCON = 0b11100000; // Global, Peripheral, TMR0 interrupts on
// Main loop. Process any 'background' tasks.
while(1)
{
// Do your normal stuff here...
}
} // main()
static void interrupt sensor_interrupt(void)
// Interrupt handler.
{
// An interrupt has occurred.
if (TMR0IF) // Is it TMR0 ?
{
// Occurs every 0.128 mS with a 8.00 MHz clock.
TMR0IF = 0; // clear the interrupt flag
TMR0 = 0x66; // reset the timer period
ms20_tick++;
if (ms20_tick > MS20_TICKS)
{
// Do this stuff every 20 mS.
ms20_tick = 0;
// Start a servo pulse, for example...
}
second_tick++;
if (second_tick > SECOND_TICKS)
{
// Do this stuff every second.
second_tick = 0;
// Blink the LED.
if (led_image == 0)
{
LED = 1;
led_image = 1;
}
else
{
LED = 0;
led_image = 0;
}
}
}
return;
} // sensor_interrupt()
Pete