Show Posts
Pages: [1] 2 3 ... 115
1  Using Arduino / Programming Questions / Re: Conditional using a float that is "-0" and how that works on: Today at 04:37:19 am
Try:
Serial.print(currentDbLevel,6);

Are the numbers the same at 6dp? Or have they just been rounded by the print function.
2  Using Arduino / Programming Questions / Re: #define, int or const int on: July 19, 2014, 08:17:29 am
Not nonsense, in fact you prove the point, thanks

#define ABC 123.456 * 789
#define ABC_DEF 654.321

void setup()
{
  Serial.begin(115200);
  Serial.println(ABC);
  Serial.println(ABC_DEF);
  Serial.println(123.456 * 789_DEF);
}

void loop(){}

That doesn't compile because 789_DEF doesn't exist, and yet you have tried to use it?!?
The second print and the third print are not the same thing, nor does the pre-processor make the second one into the third one. Try compiling it without your added nonsense and it works fine! Try this:
Code:
#define ABC 123.456 * 789
#define ABC_DEF 654.321

void setup()
{
  Serial.begin(115200);
  Serial.println(ABC);
  Serial.println(ABC_DEF);
}

void loop(){}
What do you get? I'll bet you £50billion that it compiles fine and prints out exactly:
97406.78
654.32

I proved in my post the exact opposite of what you were saying, and in fact your last post just proved that what you are saying is nonsense.


It resolves, but also resolves OTHER things you might not have wanted to resolve

In my experience on my leonardo, the compiler DOES "overlap" defines, try it
Like hell it does - and yes I did try it. Plus the compiler for the Leonardo is the same for the Uno or Mega, so the board makes no difference at all.




Back to your other point, in terms of constant values, there is no difference is space consumed between a #define and a const with the exception of arrays - my point about arrays was simply that a const does under certain circumstances still use SRAM.
What I was trying to get across is that if you use a const int, when a const unsigned char would do, it is just going to produce sub optimal code and increased flash usage.
I have no doubt that using const's is better than using #defines simply for the fact that you are in control of the variable type.
3  Using Arduino / Programming Questions / Re: #define, int or const int on: July 19, 2014, 05:52:06 am

However, the arduino IDE does NOT differentiate between two defined "variables" with the same root properly
(In my way of thinking, anyway, it can get confused)
#define ABC 123.456 * 789
#define ABC_DEF 654.321
Is replaced with
#define 123.456 * 789_DEF 654.123
That isn't too bad, it does get resolved properly, but


That is total nonsense and not true!

Try running this sketch:
Code:
#define ABC 123.456 * 789
#define ABC_DEF 654.321

void setup()
{
  Serial.begin(115200);
  Serial.println(ABC);
  Serial.println(ABC_DEF);
}

void loop(){}
It prints out:
Code:
97406.78
654.32




#define ABC XYZ
#define ABCDEF QWERTY
#define XYZDEF ABCDEFG
Gives
Gives a compile error (already defined, because ABC is replaced with XYZ in the second line)

#define ABC XYZ
#define DEF ABCDEFG
means that when you use DEF you'll get XYZDEFG not ABCDEFG


And both of those are nonsense too! Definitely doesn't give a compile error at all, nor does it give you unexpected results.

The #defines will not overlap like that. For example everything with the letters "ABC" will not be replaced. Instead everything which is exactly "ABC" will be replaced. "ABCDEFG" is not exactly "ABC", it has four other letters in it. On the other hand: ABC*DEFG will be replaced with XYZ*DEFG because the two things are treated as separate entities as is expected with a multiply operation.

For example:
Code:
#define ABC 12
#define DEFG 10
#define DEF ABC*DEFG
#define XYZ ABCDEFG

void setup(){
  Serial.begin(115200);
  Serial.println(DEF);
  Serial.println(DEFG);
  //Serial.println(XYZ); will result in an error as ABCDEFG is not defined!
}
void loop(){}
Will print:
Code:
120
10



So, I started looking at consts.
Well, to my surprise,
Using const int i_variable_for_whatever does NOT use memory under ant circumstances that I have encountered so far.

As I mentioned earlier. They will not use RAM, but they will use memory! The constants get embedded into the machine code and so use Flash. If you use an int instead of a byte, it will waste one instruction (2bytes flash) adding in an unnecessary ldi instruction - it also produces sub-optimal code due to additional register usage in areas like interrupts.

However there is a circumstance where RAM is used even for const variables. Consider this:

Code:
const char bob[4] = "Hi!";

void setup(){
  Serial.begin(115200);
  Serial.println(bob);
}
void loop(){}
Code:
158: c8 01       movw r24, r16
 15a: 60 e0       ldi r22, 0x00 ; 0   //Load the address of the array in SRAM
 15c: 72 e0       ldi r23, 0x02 ; 2   //Load the upper byte of the address in the SRAM
 15e: 0e 94 01 05 call 0xa02 ; 0xa02 <_ZN5Print7printlnEPKc> //Call print, which will iterate through
This uses 4 bytes of RAM for the bob variable.

In fact anything which uses pointers (e.g. array) will generate RAM if you use a variable as the array index - if you think about it, how else does it access the data - it would have to use a series of if-elseif statements. In the above example, the print function iterates through each element in the array as it sends it to the serial port, hence you have a variable index and hence RAM is consumed.
If on the other hand a constant is used as the index at every instance of its use, then no RAM will be used as it is smart enough to replace the array access with the value at the known index. Building on the above example, this next one uses no RAM as the array is only ever accessed with a constant index. Of course it uses more flash as there are more function calls. It is probably a lot slower too.
Code:
const char bob[4] = "Hi!";

void setup(){
  Serial.begin(115200);
  Serial.print(bob[0]);
  Serial.print(bob[1]);
  Serial.print(bob[2]);
  Serial.println(bob[3]);
}
void loop(){}
Code:
 Serial.print(bob[0]);
 158: c8 01       movw r24, r16
 15a: 68 e4       ldi r22, 0x48 ; 72           ----- Load the 'H' character, ldi doesn't use ram
 15c: 0e 94 d8 04 call 0x9b0 ; 0x9b0 <_ZN5Print5printEc>
  Serial.print(bob[1]);
 160: c8 01       movw r24, r16
 162: 69 e6       ldi r22, 0x69 ; 105          ----- Load the 'i' character, ldi doesn't use ram
 164: 0e 94 d8 04 call 0x9b0 ; 0x9b0 <_ZN5Print5printEc>
  Serial.print(bob[2]);
 168: c8 01       movw r24, r16
 16a: 61 e2       ldi r22, 0x21 ; 33           ----- Load the '!' character, ldi doesn't use ram
 16c: 0e 94 d8 04 call 0x9b0 ; 0x9b0 <_ZN5Print5printEc>
  Serial.println(bob[3]);
 170: c8 01       movw r24, r16
 172: 60 e0       ldi r22, 0x00 ; 0            ----- Load the null character, ldi doesn't use ram
 174: 0e 94 00 05 call 0xa00 ; 0xa00 <_ZN5Print7printlnEc>




p.s. if you look at the ldi op code it doesn't use SRAM, you can see the constant embedded in the instruction:
61 e2 = ldi 0x21 - see the 2 and the 1?
60 e0 = ldi 0x00 - see the 0 and the 0?
68 e4 = ldi 0x48 - see the 4 and the 8?
4  Using Arduino / Programming Questions / Re: #define, int or const int on: July 17, 2014, 03:26:28 am
Its too quiet to tell you the truth, some warnings would be useful.

The IDE adds '-w' which means Suppress all warnings, even the ones you mentioned should happen do not ( I agree they should be shown ). So just cos you don't see any warnings, does not mean they never happen. Its a mistake if you ask me, some warnings will point out logic errors which will compile fine.

In 1.0.5/1.5.3 and greater, you only get error messages. I guess they base it on the fact newbies can't understand the messages spewed out. Kind of defeats the verbose output mode, the last error is always shown.
Time to switch to UECIDE! At least that way you get a proper build environment - and can even change the compiler options if you want.
5  Using Arduino / General Electronics / Re: Different A4988 stepper drivers give different results on: July 16, 2014, 02:42:13 pm
Have you definitely got the motor coils wired up right?

Remember that on the easy driver, one coil connects to A and the other to B.
On the Pololu board, one coil connects to 1A/1B, the other connects to 2A/2B
6  Using Arduino / Programming Questions / Re: #define, int or const int on: July 16, 2014, 11:49:34 am
It looks like "const int" is a good habit to get into for when I get on to more difficult code and, eventually, writing my own. I hadn't seen "const byte" used in the (limited number of) examples I've seen, but I can see how it will save RAM in a bigger application.
If it is not used in an array, then it will probably not save any RAM at all - generally const variables (which don't involve pointers) are simply optimised into 'ldi' instructions wherever they are used - much like #defines.
7  Using Arduino / Microcontrollers / Re: Why 16 Mhz clock??? on: July 16, 2014, 08:22:36 am
1/16000000 = 62.5nS x 16 = 1uS.
I think that works out nice & convenient.
A 16.384MHz crystal would be very useful - would make a very nice millis() function (16384000/64/256 = 1kHz). Granted it would make timing microseconds more difficult and 'nop' instructions would no longer accurately add up to a us.
8  Using Arduino / Microcontrollers / Re: How establish communication between Attiny and Arduino One? on: July 16, 2014, 04:43:55 am
I'm fairly sure he has many Tinys talking to an Arduino Uno, in which case that's all backwards (not useful).

The only bus that easily allows multiple devices to be attached to it is I2C.
Ah, hadn't picked that up from his post. Yes, if you have multiple devices I2C is by far the best bus.
9  Using Arduino / Microcontrollers / Re: How establish communication between Attiny and Arduino One? on: July 16, 2014, 04:09:06 am
Alternatively, if you want to use serial, there is another way.

I presume (unless I am missing something) that an Arduino One is an Uno?
If so you can put it into Synchronous mode, by calling these lines in setup() of the Arduino sketch:
Code:
Serial.begin(2400); //the actual baud rate will be 4 times higher in sync mode, so this is 9600.
UCSR0C &= ~_BV(UMSEL01);
UCSR0C |= _BV(UMSEL00);

Connect the XCX pin (Digital Pin 4) of the Arduino to an interrupt pin of the ATTiny (you can either use the Analog Comparator AIN1 pin, or either the External Interrupt 0 or 1 pins depending on which ATTiny you have). Then connect the RX and TX to any pin on the ATTiny on the same Port as the interrupt pin.
I have attached a library which will allow the ATTiny to be a USART slave. In this library there is a "TinyUSARTConfig.h" file. Set the port bits and names you have used in this file as directed. If you used an interrupt different from INT0, you need to configure that as well.

And the following is an example sketch:
Code:
#include "TinySoftwareUSART.h"
#include "TinyUSARTConfig.h"

USARTRingBuffer rx_buffer = {{0},0,0};
USARTRingBuffer tx_buffer = {{0},0,0};//These two lines are required and are the Serial comms buffer.

TinySoftwareUSART USART = TinySoftwareUSART(); //Make an instance of USART

void setup()
{
    USART.begin(); //No need to specify a baud rate, as that is governed by the Arduino Uno (master).
    USART.println("Welcome!");
}

void loop(){
    if (USART.available()){
        USART.write(USART.read()); //echo.
    }
}

Basically this gives you the advantage of Asyncronous Serial communication, but uses a clock line to time the bits allowing for full duplex operation without the ATTiny having to time out the Serial baud rate.


(Side note, I have tested this on two different ATTiny devices, but it should work on any which have the GPIOR0, GPIOR1 and GPIOR2 listing in the register description of the datasheet, those are used by the library).
10  Using Arduino / Microcontrollers / Re: Why 16 Mhz clock??? on: July 16, 2014, 03:49:00 am
One problem with running at 20MHz is that 20 is not a power of 2 which can make some timings that require divisions complicated.

...R
But then neither is 16MHz, it just has two more 2's as its prime factors (16MHz is divisible by 2^10 vs. 20MHz by 2^8 - they both have lots of 5's in them too).
11  Using Arduino / Microcontrollers / Re: Why 16 Mhz clock??? on: July 16, 2014, 02:41:05 am
All the timers will work in exactly the same way with an external clock vs. a crystal/resonator.

The reason it works without changing the fuse is the way the crystal oscillator work - it is essentially just a NOT gate (1 input, 1 output) which has a crystal connected across it. If you feed a clock signal into the input of the gate it will still feed a clock signal in. Had you connected it to the output of the gate, it wouldn't be happy.
12  Using Arduino / Programming Questions / Re: why do we use int instead of long on: July 15, 2014, 06:18:37 pm
This was my *ugly* solution at the time:
Code:
    #ifdef _LIB_SAM_
        #define DEFAULT_DATA_TYPE unsigned int
        #define DEFAULT_MID_DATA_TYPE unsigned int
        #define DEFAULT_WIDE_DATA_TYPE unsigned int
        #define DEFAULT_SIGNED_DATA_TYPE signed int
        #define DEFAULT_MID_SIGNED_DATA_TYPE signed int
        #define DEFAULT_WIDE_SIGNED_DATA_TYPE signed int
    #else
        #define DEFAULT_DATA_TYPE unsigned char
        #define DEFAULT_MID_DATA_TYPE unsigned int
        #define DEFAULT_WIDE_DATA_TYPE unsigned long
        #define DEFAULT_SIGNED_DATA_TYPE signed char
        #define DEFAULT_MID_SIGNED_DATA_TYPE signed int
        #define DEFAULT_WIDE_SIGNED_DATA_TYPE signed long
    #endif
Then I just used those defines for data types, e.g.:
Code:
gLCD(DEFAULT_DATA_TYPE RS, DEFAULT_DATA_TYPE CS, DEFAULT_DATA_TYPE SCLK, DEFAULT_DATA_TYPE SDATA, SpeedMode speed = NORMAL_SPEED);
As I said, it looks *awful*. But myeh, it works.
13  Using Arduino / Microcontrollers / Re: Why 16 Mhz clock??? on: July 15, 2014, 06:17:04 pm
Because not all parts can run at 20MHz, and I believe way back when, the chosen ATMega was limited to 16MHz.
14  Using Arduino / Programming Questions / Re: why do we use int instead of long on: July 15, 2014, 04:24:08 pm
Looking at the resultant code, the uint24_t's are pretty good.
Which processor? AVR?
Or on a processor like pic32 or ARM that has actual 32 bit registers?
I'd be curious how it does on the processors with the larger registers.

--- bill

I'm talking about AVRs. Generally with 32bit machines the most efficient variable size is 32bits - take my Nokia 6100 LCD library, that was ported to the Due as well and it was stupidly slow until I changed all the bytes and chars to (unsigned) ints [i.e. 32bit] at which point it sped right up.
15  Using Arduino / Programming Questions / Re: why do we use int instead of long on: July 15, 2014, 12:55:10 pm
Looking at the resultant code, the uint24_t's are pretty good. Haven't done any speed tests on multiply/divide and such yet, but for addition/subtraction/general stuff, it comes out great - especially if you want 24bit colour (RGB) and don't want to waste time processing the extra byte.

You do have to add this to your sketch:
typedef __uint24 uint24_t;
typedef __int24 int24_t;
As they have slightly different names than usual. But after that it is fine.
Pages: [1] 2 3 ... 115