Show Posts
Pages: [1] 2 3 ... 55
1  Using Arduino / Programming Questions / Re: (x)printf formatting question on: September 29, 2014, 11:27:46 am
I'm confused, so I made two test programs.
The '*' format can also be used with integers, for example for the width.
I tried many things for the Arduino, but I can't make it work. It is not implemented or it is a bug, since the string is always terminated when a format with '*' is found.

I suppose I should have just done an online search. On this page: http://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html  and scroll about 90% of the way down:

Quote
Limitations:

        The specified width and precision can be at most 255.

Notes:

        For floating-point conversions, if you link default or minimized version of vfprintf(), the symbol ? will be output and double argument will be skiped. So you output below will not be crashed. For default version the width field and the "pad to left" ( symbol minus ) option will work in this case.
        The hh length modifier is ignored (char argument is promoted to int). More exactly, this realization does not check the number of h symbols.
        But the ll length modifier will to abort the output, as this realization does not operate long long arguments.
        The variable width or precision field (an asterisk * symbol) is not realized and will to abort the output.


So I guess I need to write a little bit of code now....  smiley
2  Using Arduino / Programming Questions / Re: (x)printf formatting question on: September 28, 2014, 07:55:23 pm
You could write your own format string with another sprintf, but that's a work around, so I won't suggest it.

What I really am trying to do is emulate the built in Print.xxx() syntax for floating point (that is, if I do "Serial.print (123.4567, 2);" I want to get "123.46" as an output, but by using fprintf().

Since I use "fdev_open" to connect Serial to stdin and stdout (and stderr), I use those in my code.

For example, instead of doing something like this:

Code:
    Serial.print ("Heatsink temp: ");
    Serial.print (hstemp, 2);
    Serial.print (" deg C");
    Serial.println ();
/// and many more of these ridiculous concatenations to display the other sensors 

All I do is this:

Code:
    fprintf (stdout, "Heatsink temp: %.2f deg C\n", hstemp);

...but sometimes I need to have a variable number of digits precision (i.e. the "2" above) and GCC is supposed to support it (and indeed it DOES support it... but not in the AVR version).

And that is my problem. Of course I could write all kinds of hacks to get the output I want, but then I may as well just do the absurd "Print-Print-Print-Print-Print" sequences for each value I need to print.... and I don't want to do that.
3  Using Arduino / Programming Questions / Re: (x)printf formatting question on: September 28, 2014, 07:45:30 pm
Which version gcc do you use in linux ?
I assume it is not implemented (yet) in the avr-gcc.

I can't find more information on it, and I must admit that I never used the variable precision %.*f

The Linux version:
root@michael:/# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-unknown-linux-gnu/4.9.1/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-4.9.1/configure
Thread model: posix
gcc version 4.9.1 (GCC)


The AVR version:
root@michael:/# avr-gcc -v
Using built-in specs.
COLLECT_GCC=avr-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/avr/4.8.2/lto-wrapper
Target: avr
Configured with: ../src/configure -v --enable-languages=c,c++ --prefix=/usr/lib --infodir=/usr/share/info --mandir=/usr/share/man --bindir=/usr/bin --libexecdir=/usr/lib --libdir=/usr/lib --enable-shared --with-system-zlib --enable-long-long --enable-nls --without-included-gettext --disable-libssp --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=avr
Thread model: single
gcc version 4.8.2 (GCC)



Version 4.8.2 is fairly recent (release date October 16, 2013). The AVR-GCC docs list the variable format specifier option, so it should be supported...... I would think?

4  Using Arduino / Programming Questions / Re: (x)printf formatting question on: September 28, 2014, 07:36:07 pm
Which version of the IDE are you using. I'm using 1.5.7 and the line:

Code:
 sprintf (buffer, "val is %.2f\n", val);

for me produces:

Code:
val is ?

Clearly there's some difference between the two.

The Arduino IDE (all of them as far as I know) doesn't link the floating point libraries into the code in order to save memory size.

There is just a little stub that prints a question mark when trying to use a floating point printf specifier.

The floating point code CAN be linked into a compiled sketch if the proper options are placed on the compiler command line.

I edited my IDE code to add an option in Preferences to enable or disable the floating point support at will (see screenshot).

It's handy when I need to print complex lines and don't want to mess with a dozen LCD.print() and dtostrf() calls.

I know it (HORRORS!!!) uses an extra 1.5k of memory, but I have yet to run out and I've done some pretty complex stuff on a little UNO R3 and had memory (program memory) to spare.


5  Using Arduino / Programming Questions / (x)printf formatting question on: September 28, 2014, 12:49:31 pm
Hi all,

Using the Arduino IDE v1.0.5 and AVR-GCC version 4.8.2 and using the linker options to support floating point numbers (I added that option to my IDE), I can do something like this:

Code:
    char buffer [64];
    double val = 123.456789;
    sprintf (buffer, "val is %f\n", val);
    Serial.print (buffer);

...and it correctly prints "123.456790"

However, if I try to use the variable precision specifier like this:

Code:
    sprintf (buffer, "val is %.*f\n", 2, val);

It doesn't work. All it prints is "val is"

However, putting the precision specifier directly inside the line works and, as expected, this:

Code:
    sprintf (buffer, "val is %.2f\n", val);

...correctly prints this: "val is 123.46"

Am I doing something wrong? I tested my syntax in Linux GCC and it worked fine. Is there maybe a compiler or linker flag I'm missing?

Lastly, please don't tell me to use dtostrf() or any other floating point "workarounds". I need what I described above to work.

Any info will be appreciated. Thanks!

-- Roger
6  Using Arduino / Programming Questions / Re: RF program - what is uint8_t * ? on: September 27, 2014, 08:30:40 am
Thank you very much!!!!!
That was great and detail explanation and I understood the problem thanks to it!!!!!


          You are really good teacher! smiley-lol

Glad it helped you out!

If you like, here's an Arduino version of the same test code. Be sure to edit the "Serial.begin()" line to your desired baud rate (I use 115200, others use 9600, set it to what you use).

Code:
void setup (void)
{
Serial.begin (115200);

char *message = "Hello there";
char buffer [256]; // printing buffer
unsigned long str_len = (strlen (message) + 1); // grab the null too
unsigned long ptr_siz = sizeof (message);
unsigned long ptr_to_ptr_siz = sizeof (&message);
unsigned long char_siz = sizeof (char);
unsigned long char_ptr_siz = sizeof (char *);
int x;

sprintf (buffer, "The length of the string (including the null) is %lu\r\n", str_len);
Serial.print (buffer);

sprintf (buffer, "The string is %s\r\n", message);
Serial.print (buffer);

sprintf (buffer, "The string starts at 0x%08X\r\n", message);
Serial.print (buffer);

sprintf (buffer, "The address of the pointer to 'message' is 0x%08X\r\n", &message);
Serial.print (buffer);

sprintf (buffer, "The pointer to 'message' uses %lu byte%s\r\n", ptr_siz, (ptr_siz == 1) ? "" : "s");
Serial.print (buffer);

sprintf (buffer, "The pointer to the address of 'message' uses %lu byte%s\r\n", ptr_to_ptr_siz, (ptr_to_ptr_siz == 1) ? "" : "s");
Serial.print (buffer);

sprintf (buffer, "The size of a char in memory is %lu byte%s\r\n", char_siz, (char_siz == 1) ? "" : "s");
Serial.print (buffer);

sprintf (buffer, "The size of a char POINTER in memory is %lu byte%s\r\n", char_ptr_siz, (char_ptr_siz == 1) ? "" : "s");
Serial.print (buffer);

sprintf (buffer,
"\r\n"
"Address\t\tData\tChar\r\n"
"=======\t\t====\t====\r\n"
);
Serial.print (buffer);

for (x = 0; x < str_len; x++) {
sprintf (buffer, "0x%08X\t0x%02X\t %c\r\n", (message + x), message[x], message[x]);
Serial.print (buffer);
}

sprintf (buffer, "\r\nBye!\r\n");
Serial.print (buffer);

// end of setup()
}

void loop (void)
{
// we don't use loop() here
}

On my Arduino UNO R3, this code outputs the following. Take note of the differences in the output of the 64 bit Linux version and the 16 bit Arduino version... particularly the pointer sizes:

The length of the string (including the null) is 12
The string is Hello there
The string starts at 0x00000100
The address of the pointer to 'message' is 0x000008FA
The pointer to 'message' uses 2 bytes
The pointer to the address of 'message' uses 2 bytes
The size of a char in memory is 1 byte
The size of a char POINTER in memory is 2 bytes

Address         Data    Char
=======         ====    ====
0x00000100      0x48     H
0x00000101      0x65     e
0x00000102      0x6C     l
0x00000103      0x6C     l
0x00000104      0x6F     o
0x00000105      0x20      
0x00000106      0x74     t
0x00000107      0x68     h
0x00000108      0x65     e
0x00000109      0x72     r
0x0000010A      0x65     e
0x0000010B      0x00
    
Bye!



Have fun!

7  Using Arduino / Programming Questions / Re: RF program - what is uint8_t * ? on: September 25, 2014, 11:56:50 am
While most of the descriptions are correct, statements like this:
Quote
When you remove the *, you are changing the variable type from pointer to char to char. A char can hold ONE character. Obviously, "hello" is NOT one character.
imply that the reason it does not work is that "Hello" is more than one character, not that a pointer is not the same kind of object as a scalar.

OK, obviously the OP isn't a C programming expert (yet) since he didn't know about pointers and such. Therefore, I tried to make my explanation as easy to understand as possible without throwing in things that would be confusing.

Ever take a class where a SIMPLE calculation that can be done on a 4 function calculator is instead explained in the textbook using a level of math far above the understanding of most people and you are expected to memorize formulas?

Well, the formulas evaporate from the brain 10 minutes after you take the final exam, never to be remembered again.

However, if a GOOD teacher instead EXPLAINS how it works, THEN shows you the math, you say "Ah-ha! Now I get it!" and you don't need to memorize anything because with your UNDERSTANDING of the concept, you can DERIVE the formula any time you wish.

That's the difference between a good teacher and most other teachers / professors.

I try to teach through UNDERSTANDING. The nitty gritty bs about "scalar objects" will come before the OP in due time. For now he needs the basics.

(edit to add): I was wondering what you were talking about. I never said
Quote
When you remove the *, you are changing the variable type from pointer to char to char. A char can hold ONE character. Obviously, "hello" is NOT one character.
but now I see you were replying to someone else. Anyway, the rest of this post applies, so.....
8  Using Arduino / Programming Questions / Re: RF program - what is uint8_t * ? on: September 25, 2014, 10:21:26 am
There is some confusion.

Code:
char message = "Hello, there"; [
fails because in this context "Hello,there" decays to a pointer to a string in memory the 'const char *', and it is illegal, and nonsensical to store that in a space reserved for a single char. It has nothing to do with the length of the string.
Code:
char message = "H";
will fail just as badly.

...and the point is?
9  Using Arduino / Microcontrollers / Re: Can't Use an Arduino as ISP on: September 25, 2014, 09:39:11 am
I have a Duemilanove with the Arduino as ISP sketch put on it, and with the wires to hook up another arduino and I included the cap between the reset and ground. I wire it up to a target Arduino, an UNO to test it out, I line up the Tools as needed, and try an upload and.... no dice.

I'm running Ubuntu 13.10 and I tried multiple versions of the IDE software. I can put sketches on the Duemilanove and UNO normally with the system and the versions of the IDE. Needless to say I double checked the wiring between the two. I need to solve this because there is NO way I can EVER program a Leonardo except by using an ISP device.

NOTE: Please do not tell me that Leonardos work on Linux. If it works on YOUR Linux box, you merely got lucky.

I don't know what to tell you. The ISP sketch works fine for me (Kubuntu 14.04, 64 bit). Of course, it doesn't properly handle the Arduino MEGA and is all around sort of flakey to use (reset timing is tricky).

I heartily suggest you buy yourself an Atmel AVR-ISP-MKII (click the picture for the link):



It "just works", no fuss no muss (works fine on Linux, by the way).

Note that the Atmel ISP does not provide power over the ISP connection. You either need to connect a separate power source to your target device or else hack your ISP to forward USB power to the ISP pin. The cover pops off easily, so you won't damage anything by opening it.

To do the hack, see these pics - click a pic for higher resolution:







Obviously (as the pics show) the diode has to point towards the ISP header!  smiley

Good luck!
10  Using Arduino / Programming Questions / Re: RF program - what is uint8_t * ? on: September 25, 2014, 09:16:47 am


Why when I change the:
Code:
char *message = "Hello";
to
Code:
char message = "Hello";
  the compiler gives me this error: invalid conversion from 'const char*' to 'char' ? What is the purpose of the '*' sign?


OK...

char message;  assigns the name "message" to a one byte area in memory. That one byte area is pointed to by either a 16, 32 or 64 bit pointer (pointer size depends on the processor and compiler).

But, only one byte of memory is allocated, so, ALL you can do is something like this:
char message = 'A';

That is, you can only store one byte in it. If you try this:
char message = "Hello there";

The compiler gives you an error because it cannot put a whole string in one byte.

Now look at this (note the * character)
char *message = "Hello there";

What this does is tell the compiler to assign storage space for 12 bytes ("Hello there" plus a null terminator). The * character means that now the variable name "message" points to the memory address of the first character (i.e. the letter "H").

The compiler counted how many characters were in the string, reserved memory for them and finally returned a pointer to it for you to use.

Here's an example of what the memory map would look like:

Code:
char *message = "Hello there";

ADDR    DATA
0x0120  H
0x0121  e
0x0122  l
0x0123  l
0x0124  o
0x0125  <space>
0x0126  t
0x0127  h
0x0128  e
0x0129  r
0x012A  e
0x012B  0x00H

....
....
....

message

0x0150  0x20
0x0151  0x01

You see? The STRING "message" is stored starting at address 0x0120. The variable that points to it is stored at address 0x0150 and 0x0151 (a 16 bit location, and "little endian" backwards) and it contains the value "0x0120" (the start address of the string).

Now check this code out. I did it in Linux, but you can also do it in Arduino. Just change the "fprintf" calls to "Serial.print()".

If you do this, note the differences in:
* The size of the pointers
* The addresses things are stored at

Code:
#include <stdio.h>
#include <string.h>

int main (void)
{
char *message = "Hello there";
unsigned long str_len = (strlen (message) + 1); // grab the null too
unsigned long ptr_siz = sizeof (message);
unsigned long ptr_to_ptr_siz = sizeof (&message);
unsigned long char_siz = sizeof (char);
unsigned long char_ptr_siz = sizeof (char *);
int x;

fprintf (stdout, "The length of the string (including the null) is %lu\n", str_len);
fprintf (stdout, "The string is %s\n", message);
fprintf (stdout, "The string starts at 0x%08X\n", message);
fprintf (stdout, "The address of the pointer to 'message' is 0x%08X\n", &message);
fprintf (stdout, "The pointer to 'message' uses %lu byte%s\n", ptr_siz, (ptr_siz == 1) ? "" : "s");
fprintf (stdout, "The pointer to the address of 'message' uses %lu byte%s\n", ptr_to_ptr_siz, (ptr_to_ptr_siz == 1) ? "" : "s");
fprintf (stdout, "The size of a char in memory is %lu byte%s\n", char_siz, (char_siz == 1) ? "" : "s");
fprintf (stdout, "The size of a char POINTER in memory is %lu byte%s\n", char_ptr_siz, (char_ptr_siz == 1) ? "" : "s");

fprintf (stdout,
"\n"
"Address\t\tData\tChar\n"
"=======\t\t====\t====\n"
);

for (x = 0; x < str_len; x++) {
fprintf (stdout, "0x%08X\t0x%02X\t %c\n", (message + x), message[x], message[x]);
}

fprintf (stdout, "\nBye!\n");

return 0;
}

And running it produces:

The length of the string (including the null) is 12
The string is Hello there
The string starts at 0x004009B8
The address of the pointer to 'message' is 0xE2395968
The pointer to 'message' uses 8 bytes
The pointer to the address of 'message' uses 8 bytes
The size of a char in memory is 1 byte
The size of a char POINTER in memory is 8 bytes

Address         Data    Char
=======         ====    ====
0x004009B8      0x48     H
0x004009B9      0x65     e
0x004009BA      0x6C     l
0x004009BB      0x6C     l
0x004009BC      0x6F     o
0x004009BD      0x20
0x004009BE      0x74     t
0x004009BF      0x68     h
0x004009C0      0x65     e
0x004009C1      0x72     r
0x004009C2      0x65     e
0x004009C3      0x00

Bye!


Notice that my test shows 8 byte (64 bit) pointers. I'm using 64 bit linux. You will probably see 2 byte (16 bit) pointers if you run this on an Arduino.

Hope this helps explain pointers........  smiley

-- Roger
11  Using Arduino / Microcontrollers / SAMA5D3 based board from Atmel - supported by IDE 1.5.x? on: September 25, 2014, 07:36:47 am
Well, the title says it all.

I received an email notification about a neat microcontroller board made by Atmel that seems like it has a LOT of possibilities (click image for link):


Anyone know if the version 1.5.x IDE will support this board?

Thanks!

(edit to add): Here's more info about the board: http://www.element14.com/community/community/designcenter/sama5d3xplained

-- Roger
12  Using Arduino / Programming Questions / Re: knock sensor problem on: September 10, 2014, 08:04:24 am
Quote
would expect the analog reading to be zero if the piezo is not being touched and there is a 1 meg to ground, yes?
No.
Quote
Or is he seeing leakage from the A/D converter circuitry that a 1 meg can't swamp out?
It is not leakage it is pick up interference. In effect this input is floating.

The 328p data sheet (Rev. 8271H – 08/2013, page 301) states that the leakage current of any I/O pin is 1 microampere (max) for both low and high level.

So, a 1uA current through a 1 meg resistor is 1 volt. With an A/D output range of 0 to 1023, 1 volt would show as a reading of around 205 (decimal). The OP was getting a reading of 322...327 which makes me suspect that he WAS seeing leakage.

Also, the datasheet says that something driving the A/D input should have an output impedance of 10K ohms or less, to swamp out the internal capacitance and leakage current of the input.

Lastly, how can you say that a pin connected to VCC or GND through a 1 meg resistor is "in effect, floating"? Floating means there is nothing defining it's state (i.e. a resistor or an active driver) or in other words an OPEN, UNCONNECTED input.

1 meg is less than ideal for most digital uses (bias for a cmos inverter crystal oscillator circuit being one exception) but it certainly doesn't result in a "floating" input.

I agree with you though....... that piezo circuit as posted is a LOUSY design.
13  Using Arduino / Programming Questions / Re: knock sensor problem on: September 10, 2014, 07:42:06 am
I will try what Krupski suggested but I really don't want to tie up 2 analog pins.

Well what would work even better is an op-amp. Connect the piezo between the inverting and non-inverting inputs and setup the gain to give you a nice strong (volts range) signal from the piezo when a knock is detected.

I would suggest using an op-amp that is designed for single supply use, then run it from the 5 volt rail of the Arduino and bias the non-inverting pin at 1/2-1/2.

Pros:
(1) Single supply op-amp does not need a biploar supply.
(2) Protection - the op-amp output cannot swing below zero nor above 5 volts, thereby protecting the analog input pin
(3) Better signal - the differential connection of the piezo will give you the common mode noise rejection you need, and the gain will give the Arduino a nice, reliable signal. You can even add a few capacitors and resistors to make a high-pass or band-pass filter to further clean up the piezo signal.
(4) You will then only need one analog input on the Arduino.

Cons:
(1) More parts
(2) More cost


Lastly, you may want to add a snubber (two 1N914 or 1N4148 diodes in parallel, opposite directions) to clamp the piezo output to approximately +/- 0.7 volts. A piezo can produce very high voltages if given a step input (that's how gas grill igniters work!). An accidental tap or touch on the piezo could burn out the op-amp without the diodes.

|--->|---|
|---|<---|

Above is what I mean... back to back diodes.

Hope this helps.
14  Using Arduino / Programming Questions / Re: Calculate RPM and Speed / Store to varibale on: September 09, 2014, 09:52:42 am
Quote
I would need something similar, a snippet which I can include in my code to invoke it something like.

ReadValues(rpm, kmh);

To store the value to a variable.
So, fire up the IDE and start writing. The homework hotline is closed for vacation. It'll open again in 6 months.

If you look at his past posts (follow the link he posted) you will see that this is obviously not homework.
15  Using Arduino / Programming Questions / Re: knock sensor problem on: September 09, 2014, 09:15:22 am
Quote
I get a value fluctuating between 322 and 327 even if the piezo is not being 'knocked'.
That sounds fine.
The load resistor of 1M is too high to reduce all the interference getting into the pin, so there will be some background variations.

I would expect the analog reading to be zero if the piezo is not being touched and there is a 1 meg to ground, yes?

Or is he seeing leakage from the A/D converter circuitry that a 1 meg can't swamp out?
Pages: [1] 2 3 ... 55