Atmega328p Load cell

Go To Last Post
23 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I went through topics here regarding this question, but none of them were succesfully resolved and I want to start with basics and build on it to add more advanced stuff.

 

I have Atmega328p + Hx711 + Load cell.

 

I started from the code in Hx711 datasheet, here is what I have:

#define F_CPU 8000000UL		// 8 MHz clock speed
#define BAUD 9600			// define baud
#define BAUDRATE ((F_CPU)/(BAUD*16UL)-1)

#include <avr/io.h>
#include <util/delay.h>

// Macros
#define setbit(port, bit) (port) |= (1 << (bit))
#define clearbit(port, bit) (port) &= ~(1 << (bit))
#define getbit(port, bit) ((port) & (bit))

#include "USART.h"

unsigned long ReadCount(void)
{
	unsigned long Count;
	unsigned char i;
	setbit(PORTD, PD5);
	clearbit(PORTD, PD6);
	Count=0;
	while(getbit(PORTD, PD5));
	for (i=0;i<24;i++) {
		setbit(PORTD, PD6);
		Count=Count<<1;
		clearbit(PORTD, PD6);
		if(getbit(PORTD, PD5)) Count++;
	}
	setbit(PORTD, PD6);
	Count=Count^0x800000;
	clearbit(PORTD, PD6);
	return(Count);
}

int main(void)
{
	DDRD |= (1<<PD6);       // SCK 
	DDRD &= ~(1<<PD5);      // DT
	
	// Input variable
	char* data;
	
	// USART init
	USART_init(BAUDRATE);
	
	unsigned long datavar;
	
    while(1) {
	    datavar = ReadCount();
	    data = datavar + '0';
	    USART_write_string(data);
		
		_delay_ms(1000);
    }
}

 

USART is tested and works fine, therefore I don't include it.

 

Unfortunatelly all I get from this code in Terminal are "60 60 60 60 60" (HEX), repeatedly.

 

My Hx711 is wired like this:

E+ to red wire of the load cell

E- to black wire of the load cell

A- to white wire of the load cell

A+ to green wire of the load cell

 

SCK to PIND6

DT to PIND5

GND to GND

VCC to 5V

 

Could you help me where is the problem?

 

Thank you.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello, wabi, and welcome to AVR Freaks -

 

Most load cells require a differential analog measurement between the two midpoints of the cell bridge. I don't see any analog or ADC at all.

 

You don't say what A+ or A- are.

 

And what "count" are you reading? What is its purpose?

 

We need a LOT more information before much useful help can be offered.

 

Checking on the internet, I finally see that Hx711 looks like a quasi-SPI 24bit ADC. So, I can't help you much.  But the question of "count" still stands. What are you counting?

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Sun. Apr 1, 2018 - 01:53 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

HX711 claims to be 24bit, but those bits are never going to be real bits.

Some preleminary tests I did suggested I could get about 14 effective bits out of it without averaging or other tricks.

I am not really in the mood to spend time at your code, but here is the lib I wrote for myself.

This lib is a work in progress, and got a bit neglected some time ago...

You might also want to have a look at other people's code:

https://github.com/search?utf8=%E2%9C%93&q=hx711&type=

 

But HX711 is a quite simple device.

Because all your bytes are the same it is almost certain that your SPI interface does not work properly, or the data you read via SPI is not send to the UART properly, Might even be a wrong baudrate or something.

 

In cases like this I would normally start with Sigrok and my trusty USD5 logic analyser.

 

Edit: Got some of the kinks out of my keyboard.

Attachment(s): 

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

Last Edited: Sun. Apr 1, 2018 - 03:50 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jim
It looks like the OP is bit banging SPI and "count" is the reading from the A/D converter. In the gaging industry they call ADC readings 'counts'.

Jim

Edit:
Why not use the SPI in the 328 instead of bit banging?

@Paulvdh, lighten up a little for cryin' out loud. Go grab a Heineken;)

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

Last Edited: Sun. Apr 1, 2018 - 03:12 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh gosh, did I do it again?

I'm usually quite friendly, but my keyboard turns my words around.

Too many curls in the cord I guess.

 

At the moment is already past bedtime for me.

If OP is still struggling with with his code tommorow I'll compile his program and put it through my LA, but only if the code is complete.

All the USART stuff seems to be missing / in another file.

 

Just compared OP's code with the datasheet. It seems a quite literal copy from the example code.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you so much for kind responses! Paulvdg is right, I tried to alter an example code to the program, I see now it was naive.

 

I'm now looking at your library, it looks more straightforward than what I found myself, but it will take some time for me to understand what is going on in some functions, I am new to this. Could you please point me to how your main function would look like, and how is your HX711_CLK_BIT and HX711_DATA_BIT initialized? If I had a running example (a basic one), I would like to start from that to understand how it works exactly.

 

I will try to learn more based on all your responses and hopefully get back to you soon :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

wabi wrote:

I started from the code in Hx711 datasheet

Could you help me where is the problem?

 

I have not worked with the Hx711 chip, but ...

Here is your code from Post#1 (modified in RED):

#define F_CPU 8000000UL		// 8 MHz clock speed
#define BAUD 9600			// define baud
#define BAUDRATE ((F_CPU)/(BAUD*16UL)-1)

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>    // for ltoa()

// Macros
#define setbit(port, bit) (port) |= (1 << (bit))
#define clearbit(port, bit) (port) &= ~(1 << (bit))
#define getbit(port, bit) ((port) & (bit))

#include "USART.h"

unsigned long ReadCount(void) // should return signed long
{
	unsigned long Count=0; // should be signed long & initialized to 0
	unsigned char i;
	setbit(PORTD, PD5);
	clearbit(PORTD, PD6);
	Count=0;
	while(getbit(PORTD, PD5));
	for (i=0;i<24;i++) {
		setbit(PORTD, PD6);
		Count=Count<<1;
                _delay_us(1.0); // make sure clock high for at least 1 us
		clearbit(PORTD, PD6);
                _delay_us(1.0); // make sure clock low for at least 1 us
		if(getbit(PORTD, PD5)) Count++;
	}
	setbit(PORTD, PD6);
	Count=Count^0x800000;  // this is in the datasheet but I don't think it is right.
        _delay_us(1.0); // make sure clock high for at least 1 us
	clearbit(PORTD, PD6);
      
        if(Count & 0x800000) Count |= 0xff000000; // if bit23==1 then set high bits to 1  
	return(Count);
}

int main(void)
{
	DDRD |= (1<<PD6);       // SCK
	DDRD &= ~(1<<PD5);      // DT

	// Input variable
	char data[16];  // need to reserve memory for string 

	// USART init
	USART_init(BAUDRATE);

	unsigned long datavar;  // needs to be signed long

    while(1) {
	    datavar = ReadCount();
	    data = datavar + '0'; // this does NOT covert to ASCII string
            ltoa(datavar, data, 16); // convert signed long to hex ASCII string
	    USART_write_string(data);

		_delay_ms(1000);
    }
}

I hope this helps, but since it is untested there may be bugs.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is your code from Post#1 (modified in RED):

...

I hope this helps

Not to those of use with red-green colour vision deficiencies :-(

 

#define F_CPU 8000000UL		// 8 MHz clock speed
#define BAUD 9600			// define baud
#define BAUDRATE ((F_CPU)/(BAUD*16UL)-1)

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>    // for ltoa()

// Macros
#define setbit(port, bit) (port) |= (1 << (bit))
#define clearbit(port, bit) (port) &= ~(1 << (bit))
#define getbit(port, bit) ((port) & (bit))

#include "USART.h"

unsigned long ReadCount(void) // should return signed long
{
	unsigned long Count=0; // should be signed long & initialized to 0
	unsigned char i;
	setbit(PORTD, PD5);
	clearbit(PORTD, PD6);
	Count=0;
	while(getbit(PORTD, PD5));
	for (i=0;i<24;i++) {
		setbit(PORTD, PD6);
		Count=Count<<1;
                _delay_us(1.0); // make sure clock high for at least 1 us
		clearbit(PORTD, PD6);
                _delay_us(1.0); // make sure clock low for at least 1 us
		if(getbit(PORTD, PD5)) Count++;
	}
	setbit(PORTD, PD6);
	Count=Count^0x800000;  // this is in the datasheet but I don't think it is right.
        _delay_us(1.0); // make sure clock high for at least 1 us
	clearbit(PORTD, PD6);

        if(Count & 0x800000) Count |= 0xff000000; // if bit23==1 then set high bits to 1 
	return(Count);
}

int main(void)
{
	DDRD |= (1<<PD6);       // SCK
	DDRD &= ~(1<<PD5);      // DT

	// Input variable
	char data[16];  // need to reserve memory for string 

	// USART init
	USART_init(BAUDRATE);

	unsigned long datavar;  // needs to be signed long

    while(1) {
	    datavar = ReadCount();
	    data = datavar + '0'; // this does NOT covert to ASCII string
            ltoa(datavar, data, 16); // convert signed long to hex ASCII string
	    USART_write_string(data);

		_delay_ms(1000);
    }
}

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Sun. Apr 1, 2018 - 01:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
Not to those of use with red-green colour vision deficiencies :-(

So you make the changed blocks green text on a red background?

 

But you must know all aboot Red Green, right?

https://en.wikipedia.org/wiki/Th...

The Red Green Show is a Canadian television comedy that aired on various channels in Canada, ...

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So you make the changed blocks green text on a red background?

My deuteranomaly (the most common kind of colour vision deficiency) has no trouble with that.  It >>does<< have trouble telling pale red text on a paler green background from the pale green text on the same background.

 

But you must know all aboot Red Green, right?

Indeed I do.

 

"I'm a man.

But I can change.

If I have to.

I guess."

 

In fact a late friend of mine made several appearances on the show over the years.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Sun. Apr 1, 2018 - 02:08 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chuck99 wrote:
Count=Count^0x800000; // this is in the datasheet but I don't think it is right.
I agree with Chuck99, he triggered a 6 months old memory.

Have a look at my code above. The sign extension part over there is done like this:

    union {
        long Value;			// Measurement value from hx711.
        uint8_t Value_Byte[4];
    };

    Value_Byte[ 2] = GetByte( );
    Value_Byte[ 1] = GetByte( );
    Value_Byte[ 0] = GetByte( );
    Value_Byte[ 3] = (Value_Byte[ 2] & 0x80)? 0xFF : 0x00;	// Sign extend.
    return Value;

Flipping the 32th bit of a 24 bit sensor reading is going to get you nowhere.

But as I said before: The sensor is noisy. So reading all bytes as the same is a clear indication of another error.

Chuck99 also caught that. Adding '0' only works with single digit numbers, not with longs.

Chuck99 even caught the signed / unsigned error.

 

yesyesyes Three thumbs up for Chuck99.

 

Also from that same 6 months old memory:

The HX711 outputs some kind of busy signal. If you don't handle that properly in software you get false readings.

Chuck99 wrote:
I hope this helps,
It surely should help OP.

Chuck99 wrote:
ltoa(datavar, data, 16); // convert signed long to hex ASCII string
Hexadecimal is nice as a starter & for debugging purposes, but for "real world" strings base 10 instead of 16 is probably better suited.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:

Here is your code from Post#1 (modified in RED):

...

I hope this helps

Not to those of use with red-green colour vision deficiencies :-(

 

You're right Joey, I didn't think of that - just habit to use red.

 

From now on, I'll use:

Line 1

Line 2

Line 3

Line 4

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Paulvdh wrote:

Also from that same 6 months old memory:

The HX711 outputs some kind of busy signal. If you don't handle that properly in software you get false readings.

 

From the HX711 datasheet:

When output data is not ready for retrieval,
digital output pin DOUT is high. Serial clock
input PD_SCK should be low. When DOUT goes
to low, it indicates data is ready for retrieval.

By applying 25~27 positive clock pulses at the
PD_SCK pin, data is shifted out from the DOUT
output pin. Each PD_SCK pulse shifts out one bit,
starting with the MSB bit first, until all 24 bits are
shifted out. The 25th pulse at PD_SCK input will
pull DOUT pin back to high (Fig.2).

 

 

From Post#1

while(getbit(PORTD, PD5));  // wait for data ready

So that wasn't a problem.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@Chuck99 #13

Yeah, that would probably work most of the time but there is a race condition there.

So if you need to be 100% sure you have to think about it a little bit more.

But that is not OP's problem.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I must be color blind, I almost missed Wabi's response here:

For the I/O pins I always collect the definitions in the file "main.h", but you can put them elsewhere if you want, but they have to be defined somewhere...

Here is the relevant part:

/*==========================================================================
 User definitions for: main.h
--------------------------------------------------------------------------*/
#define HX711_CLK_DDR		DDRB
#define HX711_CLK_PORT		PORTB
#define HX711_CLK_PIN		PINB
#define HX711_CLK_BIT		(1<<1)

#define HX711_DATA_DDR		DDRB
#define HX711_DATA_PORT		PORTB
#define HX711_DATA_PIN		PINB
#define HX711_DATA_BIT		(1<<2)

 

The code in my HX711 library is not finished yet, but it can read the raw data from a HX711 sensor.

I still have to add functions to store and read callibration data from EEPROM, functions for averaging multipe values and more.

At the moment there are just some hard coded callibraton values in the code: "CallOffset" and "CalMul".

These have to be changed for every sensor you use.

 

But I do always try to write code in a neat and modular fashion.

That is why there are functions for reading a bit, reading a byte, reading a value etc.

Writing code in such small functions also makes them self documenting.

 

First, the library is written in C++, which is quite a different beast than C.

If you want to convert it to C then I suggest you start with a text search and remove all the "THx711::" strings.

//===========================================================================
// These functions are a quick hack to make the hx711 lib work.
//===========================================================================
char PutHex(uint8_t C) {
	C &= 0x0f;
	if(C < 10)
		return C + '0';
	else
		return C + 'A' - 10;
}

//===========================================================================
void PutS8Hex( char *pDest, long Number) {
    union {
        long Long;
        uint8_t Byte[ 4];
    };
    Long = Number;

    *pDest++ = PutHex( Byte[ 3] >>4);
    *pDest++ = PutHex( Byte[ 3] & 0x0f);
    *pDest++ = PutHex( Byte[ 2] >>4);
    *pDest++ = PutHex( Byte[ 2] & 0x0f);
    *pDest++ = PutHex( Byte[ 1] >>4);
    *pDest++ = PutHex( Byte[ 1] & 0x0f);
    *pDest++ = PutHex( Byte[ 0] >>4);
    *pDest++ = PutHex( Byte[ 0] & 0x0f);
}

//===========================================================================
// String Print a number with Fixed width and precision (decimal point).
// Signed version.
void SPrintFixed( char* Buf, int32_t n, int8_t Length, int8_t Precision) {
    char Sign;
    ldiv_t	Number;

    if( n < 0) {
        n = -n;
        Sign = '-';
    }
    else
        Sign = ' ';

    Buf[Length] = 0x00;
    Number.quot = n;
    do {
        Number = ldiv( Number.quot, 10);
        Buf[--Length] = Number.rem + '0';
        if( --Precision == 0)
            Buf[--Length] = '.';
    }while( (Length > 0) && ((Number.quot) || (Precision >= 0)) );

    if( Sign == '-') {
        if( Length > 0)
            Buf[--Length] = '-';
    }

    while(Length > 0)		// Fill remaining space with spaces.
        Buf[--Length] = ' ';
}

//===========================================================================
// Normal code is resumed here:
//===========================================================================
#include <util/delay.h>
#include "hx711.h"

int main( void) {
    
    char buffer[30];
    THx711 scale;       // Declare an instance of the THx711 object.
    
    scale.SetFunction ( Func_A_128);
    
    for( ;;) {
        scale.Measure( buffer );
        USART_write_string( buffer);    // Add your own code for sending a string.
        _delay_ms(100);
    }
}

 

While looking through my old code (which I never finished) I noticed some more sloppy parts than I thought there were.

I really only was halfway developing the hx711 library and there is lots of stray debug code in there.

In C++ you can have multiple functions with the same name, as long as there are other things to make the difference clear.

If you have problems with this function:

uint8_t THx711::Measure( char *pDest) {
    ...
}

You can simply delete or ignore it and use:

float THx711::Measure( void) {

What, did I use a float ???

Holy @#$%^&* mackerell.  That was also just for testing / debugging and I simply multiplied it with 1000 to get some kind of sensible number out of it.

	long Value = Hx711.Measure() * 1000;

Normally I always scale my values in integers / longs.

If you have a good look at the SPrintFixed () function above you wil notice that it can print a dot and numbers after that dot and there is a good reason for that.

 

With the combination of my hacked together code and C++ you might be better off with using Chuck99's advice.

As I said earlier, the 0x80000000000000000 part is wrong, you have to set a whole byte depending on the highes bit in the third byte. Something like:

long value = measure_hx711();

if ( value & 0x00800000) {
    value &= 0xff000000;        // Sign extension into 4th byte.
}

Chuck is also right about the uart string printing and he probably corrected it.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks again for a lot of help, give me a few days to test and learn and I will get back to you with the results.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi everyone,

after some time I managed to make it work! It took some time for me to understand the overall logic but after that I was able to follow Hx711 datasheet and make a functional example.

 

I started from one of the libraries I found online and also source codes from you guys and made some edits. If anyone tries to achieve the same thing here is my functional code with this Hx711 library (also with USART library for output data). Hope it helps. After I tweak it a little I will upload it to github.

 

Also I am sure there are many things that can be improved so I am open to any feedback.

 

Note: calibration data are individual.

 

 

 

Attachment(s): 

Last Edited: Sat. May 5, 2018 - 03:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Overall your code looks pretty clean, (but I did not look too deep into it).

A few remarks:

These global variables are defined in hx711.h:

uint8_t GAIN;
int32_t OFFSET;						// used for tare weight
float SCALE;	                    // used to return weight in grams, kg, ounces, whatever

Variables should never be defined in header files.

It is very uncommon to define variables in ALL CAPITALS. That is usually reserved (by convention, not by C standard) for #define'd macro's (and maybe constants).

 

You also have little helper functions to set these variables, such as: " HX711_set_scale() ".

This strongly suggests that you do not even want these variables to be visible outside of Hx711.c file.

If you move these declarations to the Hx711.c file and make them static, then you explicitly tell the compiler that these variables can not be used outside of the Hx711.c file.

Like this:

static uint8_t HX711_gain;
static int32_t HX711_offset;						// used for tare weight
static float HX711_scale;	                    // used to return weight in grams, kg, ounces, whatever

(I added the HX711_ prefix to keep the naming convention of these variables the same as the function names).

 

Also a small remark about your file name: "Hx711.c"

Why a capital and a lower case letter?

Your code looks cleaner if you also use the same naming convention here.

(For myself I always use all lower case for all filenames ( Linux is case sensitive, Other "os's" are not).

 

And have another look at my code.

The union I use for the 24 bit value prevents the shifting around of bytes, by placing them in the array in the right spot.

You also seem to ingore the maximum pulsewidth of the clock.

In my code there is a note (probably straight from the datasheet) that the HX711 goes to sleep if the clock is high for > 60us.

This might get you into trouble later, if you have a complex program and lots of interrupts are used.

 

This also seems wrong:

	// Replicate the most significant bit to pad out a 32-bit signed integer
	if(data[2] & 0x80) {
		filler = 0xFF;
	}
	else if ((0x7F == data[2]) && (0xFF == data[1]) && (0xFF == data[0])) {
		filler = 0xFF;
	}
	else {
		filler = 0x00;
	}

The middle of the 3 conditions will result in a value of 0xFF7FFFFF which is very unlikely to be valid.

I simply use:

	Value_Byte[ 3] = (Value_Byte[ 2] & 0x80)? 0xFF : 0x00;	// Sign extend.

Here the braces around filler are useless:

	value = (uint32_t)(filler) << 24;

What you want to do is make sure that filler is promoted to uint32_t before the shift is done.

Because I can not (and do not want to) remember if the cast has higher precedence than the shift, I write things like these as:

	value = ((uint32_t)filler) << 24;

But as I said before, I prefer the union way of setting the bytes in the right place, so no shift is needed.

 

Edit:

(3x) "declare" -> "define".

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

Last Edited: Mon. May 7, 2018 - 04:39 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Paulvdh wrote:
These global variables are declared in hx711.h
Err no, the problem is they are DEFINED in the header. There's no problem with variables being DECLARED in a header.

 

(Though obviously a declaration is identifiable by the use of "extern")

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Now I'm a bit confused by the difference between "declare" & "define".

(I'm still no native English speaker).

After browsing through some different tutorials it seems that these terms are often used in a sloppy and/or incomplete way.

For example:

Source: http://www.cplusplus.com/doc/tutorial/variables/

 

So, if "declare" means: "Tell to the compiler what form a variable has" and "define" means "Tell to the compiler to reserve storage space for a variable" then a line of code:

int asdf;

does both define and declare the variable asdf.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Paulvdh wrote:
After browsing through some different tutorials it seems that these terms are often used in a sloppy and/or incomplete way.

Agreed.

Paulvdh wrote:
Now I'm a bit confused by the difference between "declare" & "define".

We remember that there is something "in" a definition.  That is, storage is actually allocated.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yup, like Lee I remember it by something IN a defINition. The point is that a definition (of either variable or function) uses storage while a declaration (of either) is just prior warning of type usage.
.
It is true that a definition that occurs without prior declaration does also act as a declaration at the same time.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for the feedback, I will incorporate the changes and also I am going to add more functions that are described in the datasheet for more generic use.