Adafruit Industries, Essential service and business: NYC – Executive Order 202.6 - Read more.
0

Capacitance Measurement
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

by mikewitt on Tue Feb 27, 2007 5:18 pm

Actually I saw Chan's circuit, and thought it was pretty cool, problem is that I don't like to do math that complex (like Chan does) when time matters, because it would take multiple clock cycles. I had found the Cappels one, but I didn't have any inductors lying around, and I never saw the last one you suggested.

The circuit as-is (with 1k for r1,r2) will read up to 470uF already (it should oscillate at at 1.06Hz, or .97 times per second) it'll even read beyond that, but it will be slower.

I designed this to read values in the pF range while oscillating at close to 1MHz, because I need lots of samples per second for my purpose, and for my purpose it shouldn't deviate more than 10-15pF.

If you have an ideal frequency, then you can use the equation
((1/freq)/C)/2=r
r is the same value for each of the resistors (in ohms), C is capacitance in F, (a uF is 10^-6 F or .000001F). That'll get you started, but by this weekend I should have enough time to put together a value table.
mikewitt
 
Posts: 111
Joined: Thu Jan 04, 2007 9:18 pm
Location: KB9YJY, Wilmette, IL

by mikewitt on Sun Mar 04, 2007 6:39 pm

Ok. Sorry it's been so long since the last update, I've been working on writing the code for the AVR, and it's been slow going (mostly because I'm just learning C as I go along right now, and this is the first time I've ever written anything of my own in C, and never programmed for an AVR before, etc...) So I have a question:

If I have a SIGNAL(???) {}; function, what would the value I put in the parenthesis be if I wanted to catch a PCINT0 interrupt. When I put SIG_PCINT0 in the parenthesis, the compiler says that it is a mispelled signal handler. If I say PCINT0, it says that it expected a parenthesis before a numeric constant. On the avr sheet, it says that PCINT0 is interrupt vector 0x0002, so that is my guess as to what the numeric constant is, but then what do I put in those parenthesis?

Other than that, I'm done for the most part with the code (I think).
mikewitt
 
Posts: 111
Joined: Thu Jan 04, 2007 9:18 pm
Location: KB9YJY, Wilmette, IL

by adafruit on Sun Mar 04, 2007 9:20 pm

look in the iot13.h file (do a search for it, it depends on what OS you have) to find what the PCINT interrupt is called! :)

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

by mikewitt on Sun Mar 04, 2007 9:43 pm

Thanks, I changed it to INT0 so I can trigger on the rising edge of the pulses (if I use a PCINT vector, it continually triggers when low) the vector is SIG_INTERRUPT0.

Oh, and do you know how to use the iota() function?
mikewitt
 
Posts: 111
Joined: Thu Jan 04, 2007 9:18 pm
Location: KB9YJY, Wilmette, IL

by mikewitt on Sun Mar 04, 2007 10:52 pm

Ok. CODE!

Code: Select all | TOGGLE FULL SIZE
/*
Written 2007 by Michael Witt

Designed for the ATTiny13 AVR MCU
Changes can be made to accomodate different mcus

frequency counter v2

Referenced: http://www.atmel.com/avr
         www.ladyada.net

I am not liable for any damages caused by any means by this code.
Don't agree? Don't use it.

rewritten from scratch March 3, 2007

my notes can be found in cap_src notes.txt, they're just my thought processes when coding
I didn't write them out for the benefits of others, they're for the benefit of myself
so don't ask questions about them
*/

#include <avr/io.h>            //include standard defs.
//#include <math.h>            //include math defs (don't need it. was for fmod)
#include <avr/interrupt.h>      //include interrupt defs
//#include <avr/signal.h>      //include obsolete signal header
#include <stdlib.h>

const static char chr_0 = 0x30;
/*

these aren't needed. if it's a number, just add it to chr_0

const static char chr_1 = 0x31;
const static char chr_2 = 0x32;
const static char chr_3 = 0x33;
const static char chr_4 = 0x34;
const static char chr_5 = 0x35;
const static char chr_6 = 0x36;
const static char chr_7 = 0x37;
const static char chr_8 = 0x38;
const static char chr_9 = 0x39;
//const static char chr_dot = 0x2E;
*/
static unsigned long long int timerCk;    //this will be our clock cycle counter
static unsigned char finishedCk = 1;      //this will be our indicator if we're
                                 //done with counting clock cycles (inverse logic tho)

//this sub modified to remove optional baud rate
//you should be able to uncomment most parts, and
//add a var called baud in the dimming of the func.
//so it looks like: (i think, i removed it because
//i don't know C very well)
//void tx(unsigned long int baud, unsigned int chr) {
//oh, notes on this are available in the cap_main notes.txt file
void tx(unsigned char chr) {
   unsigned long int timer;
   for (timer = 1; timer <= 1000; timer++);
   PORTB ^= PORTB ^ (((chr - (chr % 0x80)) >> 7) << PORTB4);
   for (timer = 1; timer <= 1000; timer++);
   PORTB ^= PORTB ^ ((((chr - (chr % 0x40)) % 0x40) >> 6) << PORTB4);
   for (timer = 1; timer <= 1000; timer++);
   PORTB ^= PORTB ^ ((((chr - (chr % 0x20)) % 0x20) >> 5) << PORTB4);
   for (timer = 1; timer <= 1000; timer++);
   PORTB ^= PORTB ^ ((((chr - (chr % 0x10)) % 0x10) >> 4) << PORTB4);
   for (timer = 1; timer <= 1000; timer++);
   PORTB ^= PORTB ^ ((((chr - (chr % 0x08)) % 0x08) >> 3) << PORTB4);
   for (timer = 1; timer <= 1000; timer++);
   PORTB ^= PORTB ^ ((((chr - (chr % 0x04)) % 0x04) >> 2) << PORTB4);
   for (timer = 1; timer <= 1000; timer++);
   PORTB ^= PORTB ^ ((((chr - (chr % 0x02)) % 0x02) >> 1) << PORTB4);
   for (timer = 1; timer <= 1000; timer++);
   PORTB ^= PORTB ^ ((((chr - (chr % 0x01)) % 0x01)) << PORTB4);
   for (timer = 1; timer <= 1000; timer++);
};

void startTimer(void) {
   //this sub starts counting
   while (finishedCk) timerCk++;
};

SIGNAL(SIG_INTERRUPT0) {
   //unsigned long long int tempCk;
   long double tTime = 0;
   unsigned long int tFreq = 0;
   unsigned long int time2 = 0;
   //char letters[10];
   if (finishedCk) {
      cli();
      finishedCk = 0;
      //now read timerCk
      tTime = timerCk / 0x927C00;
      tFreq = 1 / tTime;
      //now we need to pass our info to the TX function
      for (time2 = 10000000; time2 >= 1; time2 /= 10) tx((((tFreq - (tFreq % time2)) % (time2 * 10)) / time2) + chr_0);
      sei();
   } else {
      finishedCk = 1;
      timerCk = 1;
      startTimer();
   };

};


int main (void) {
   DDRB = 0x18;   //set portB to output PORTB3,4
   MCUCR |= 0x03;   //set the INT0 to triger on rising edge of pulses
   sei();         //set enable interrupts
};


Notes: This may or may not work. I haven't tested it yet. When I test it, I'll bundle it up in a zip and post it. Right now, I just wanted to get what I have out the door.

Good Luck. I'll probably be testing it tomorrow night: I'll post fixes then. (It probably _won't_ work right now as-is, but hey, miracles happen)

Oh, and one more thing: The data is put out in ASCII at 9600 baud on PORTB4 (pin 3) the 555 timer output goes into INT0 (pin 6). There is no serial clock, (and I don't know if it'll actually work at the speed [baud] I think it will)
mikewitt
 
Posts: 111
Joined: Thu Jan 04, 2007 9:18 pm
Location: KB9YJY, Wilmette, IL

by mikewitt on Mon Mar 05, 2007 5:39 pm

Uggh.

The code (kinda) doesn't work. It's too big (It won't fit in the flash memory on the chip), and I've optimized it as far as I can (but I'm still just learning C) so I'm asking for help. If anyone can help optimize the code any further, it would be much appreciated (plus I'd mention you in the source). It is pretty close to fitting right now, as-is, but even after removing all functionality I could, it is still too large. I'll post as much as I've done later tonight.
mikewitt
 
Posts: 111
Joined: Thu Jan 04, 2007 9:18 pm
Location: KB9YJY, Wilmette, IL

by mikewitt on Mon Mar 05, 2007 6:49 pm

Ok. I got it down to a size that'll fit on the MCU (_barely_):

Code: Select all | TOGGLE FULL SIZE
/*
Written 2007 by Michael Witt

Designed for the ATTiny13 AVR MCU
Changes can be made to accomodate different mcus

frequency counter v2

Referenced: http://www.atmel.com/avr
         www.ladyada.net

I am not liable for any damages caused by any means by this code.
Don't agree? Don't use it.

rewritten from scratch March 3, 200

my notes can be found in cap_src notes.txt, they're just my thought processes when coding
I didn't write them out for the benefits of others, they're for the benefit of myself
so don't ask questions about them
*/

#include <avr/io.h>            //include standard defs.
//#include <math.h>            //include math defs (don't need it. was for fmod)
#include <avr/interrupt.h>      //include interrupt defs
//#include <avr/signal.h>      //include obsolete signal header
//#include <stdlib.h>

//const static char chr_0 = 0x30;
/*

these aren't needed. if it's a number, just add it to chr_0

const static char chr_1 = 0x31;
const static char chr_2 = 0x32;
const static char chr_3 = 0x33;
const static char chr_4 = 0x34;
const static char chr_5 = 0x35;
const static char chr_6 = 0x36;
const static char chr_7 = 0x37;
const static char chr_8 = 0x38;
const static char chr_9 = 0x39;
//const static char chr_dot = 0x2E;
*/
static unsigned int timerCk = 1;          //this will be our clock cycle counter
static unsigned char finishedCk;         //this will be our indicator if we're
                                 //done with counting clock cycles (inverse logic tho)


//this sub modified to remove optional baud rate
//you should be able to uncomment most parts, and
//add a var called baud in the dimming of the func.
//so it looks like: (i think, i removed it because
//i don't know C very well)
//void tx(unsigned long int baud, unsigned int chr) {
//oh, notes on this are available in the cap_main notes.txt file
void tx(unsigned char chr) {
   unsigned int timer;
   for (timer = 1; timer <= 1000; timer++);
   PORTB ^= PORTB ^ ((chr - (chr % 0x80)) / 2);
   for (timer = 1; timer <= 1000; timer++);
   PORTB ^= PORTB ^ (((chr - (chr % 0x40)) % 0x40) / 1);
   for (timer = 1; timer <= 1000; timer++);
   PORTB ^= PORTB ^ (((chr - (chr % 0x20)) % 0x20));
   for (timer = 1; timer <= 1000; timer++);
   PORTB ^= PORTB ^ (((chr - (chr % 0x10)) % 0x10) * 1);
   for (timer = 1; timer <= 1000; timer++);
   PORTB ^= PORTB ^ (((chr - (chr % 0x08)) % 0x08) * 2);
   for (timer = 1; timer <= 1000; timer++);
   PORTB ^= PORTB ^ (((chr - (chr % 0x04)) % 0x04) * 4);
   for (timer = 1; timer <= 1000; timer++);
   PORTB ^= PORTB ^ (((chr - (chr % 0x02)) % 0x02) * 8);
   for (timer = 1; timer <= 1000; timer++);
   PORTB ^= PORTB ^ (((chr - (chr % 0x01)) % 0x01) * 16);
   for (timer = 1; timer <= 1000; timer++);
};

void startTimer(void) {
   //this sub starts counting
   while (finishedCk) timerCk++;
};

ISR(SIG_INTERRUPT0) {
   //unsigned long long int tempCk;
   //double tTime;
   unsigned int tFreq;
   unsigned long int time2;
   //char letters[10];
   if (finishedCk) {
      cli();
      finishedCk = 0;
      //now read timerCk
      //tTime = timerCk / 0x927C00;
      tFreq = 1 / timerCk / 0x927C00;
      //now we need to pass our info to the TX function
      for (time2 = 10000000; time2 >= 1; time2 /= 10) tx((((tFreq - (tFreq % time2)) % (time2 * 10)) / time2) + 0x30);
      timerCk = 1;
      sei();
   } else {
      finishedCk = 1;
      timerCk = 1;
      startTimer();
      //while (finishedCk) timerCk++;
   };

};


int main (void) {
   DDRB = 0x18;   //set portB to output PORTB3,4
   MCUCR |= 0x03;   //set the INT0 to triger on rising edge of pulses
   sei();         //set enable interrupts
   while(1);
};


Now there's a problem. I've tried it with three different ATTiny13s, but every time when I try to load the program I get this error:
C:\cap_src>make program-cap
avrdude -p attiny13 -P com2 -c dasa -U flash:w:cap_main.hex

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9007
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed

To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "cap_main.hex"
avrdude: input file cap_main.hex auto detected as Intel Hex
avrdude: writing flash (804 bytes):

Writing | ################################################## | 100% 2.02s

avrdude: 804 bytes of flash written
avrdude: verifying flash memory against cap_main.hex:
avrdude: load data flash data from input file cap_main.hex:
avrdude: input file cap_main.hex auto detected as Intel Hex
avrdude: input file cap_main.hex contains 804 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 1.80s

avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0044
0x35 != 0x34
avrdude: verification error; content mismatch

avrdude: safemode: Fuses OK

avrdude done. Thank you.

make: *** [program-cap] Error 1

C:\cap_src>
It's usually in a different place each time (different bytes) but it always happens. Anyone have any ideas?
mikewitt
 
Posts: 111
Joined: Thu Jan 04, 2007 9:18 pm
Location: KB9YJY, Wilmette, IL

by Olaf Marzocchi on Mon Mar 05, 2007 7:50 pm

I'm sorry, I'm a newbie too.
Olaf Marzocchi
 
Posts: 73
Joined: Mon May 08, 2006 3:29 am

by mikewitt on Mon Mar 05, 2007 8:08 pm

Here's my source files, in a zip.

Contains:
cap_main.c -- Main source file
cap_main.hex -- The problematic hex file (recompiling doesn't help me)
cap_main.s -- ASM source (dunno why you'd want it, but there it is)
cap_src notes.txt -- MY notes when I was making the s/w (just syntactical things, efficiency)
Makefile -- The Makefile

http://witt.michael.googlepages.com/cap_src.zip

Can anyone post if they have any luck downloading the program to the MCU?
mikewitt
 
Posts: 111
Joined: Thu Jan 04, 2007 9:18 pm
Location: KB9YJY, Wilmette, IL

by adafruit on Mon Mar 05, 2007 9:17 pm

man that is annoying. you could try ponyprog? also check to see if you are driving the DASA programmer too fast for the micro, i think you should try slowing down the SCK speed although im not sure how exactly to do that

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

by Olaf Marzocchi on Tue Mar 06, 2007 5:25 am

I cannot help you, but I remembered this page: http://www.madoverlord.com/Robots/BRIGHTSABER.t
Maybe you could follow some of his hints to reduce the code size even further.
Olaf Marzocchi
 
Posts: 73
Joined: Mon May 08, 2006 3:29 am

by mikewitt on Tue Mar 06, 2007 10:02 am

I think I'll try ponyprog tonight, because now the code fits, it's just--for some reason--not downloading properly into memory now. Just one question though: Should I submit a bug report to WinAVR about it? Because I don't _think_ it's my code causing it, I think it's avrdude causing the problem, either that, or GCC isn't compiling code correctly (I might be able to try something that would tell me if that's the case tonight); in any case, should I send them a bug report? Anyway, thanks for the ponyprog idea.
mikewitt
 
Posts: 111
Joined: Thu Jan 04, 2007 9:18 pm
Location: KB9YJY, Wilmette, IL

by Olaf Marzocchi on Tue Mar 06, 2007 11:23 am

mikewitt wrote:Should I submit a bug report to WinAVR about it? Because I don't _think_ it's my code causing it, I think it's avrdude causing the problem, either that, or GCC isn't compiling code correctly.


I'm not an expert, but I think your code doesn't make any difference and gcc too. I mean, the problem seems to be experienced during the verification, not execution. You should be able to upload a bunch of 1234567890 and still complete the verification step.

Avrdude probably is the cause, as alternatives poor cabling (but I think you already used the programmer for other µCs) or external interferences.
Olaf Marzocchi
 
Posts: 73
Joined: Mon May 08, 2006 3:29 am

by mikewitt on Tue Mar 06, 2007 4:54 pm

After looking over the ponyprog page (just google it) it looks like neither my programming dongle (DASA) nor my MCU (ATTiny13) is supported by the program. I think I'll try a nightly build (if they have one, I cant browse sf.net's site right now because my school has blocked it) or an older build.

In any case, it's frustrating. :evil:
mikewitt
 
Posts: 111
Joined: Thu Jan 04, 2007 9:18 pm
Location: KB9YJY, Wilmette, IL

by Olaf Marzocchi on Tue Mar 06, 2007 5:11 pm

The latest version (5.3.1) does.
Olaf Marzocchi
 
Posts: 73
Joined: Mon May 08, 2006 3:29 am

Please be positive and constructive with your questions and comments.