Show Posts
|
|
Pages: 1 [2] 3 4 ... 10
|
|
16
|
Using Arduino / Programming Questions / Re: dds sine wave frequency changing
|
on: February 08, 2013, 05:22:59 pm
|
believe that i can't put analogRead in the interrupt function because of the process cost. That's certain. analogRead() takes around 100 us, and your interrupt is coming every 32 us. If you do an analogRead() inside the ISR, two or three more interrupts will occur, and be missed, before the analogRead() completes. [W]hen i put tword between disable/enable i hear some dirty noise because the clock of the loop() is too slow That's not particularly surprising, either. Calculating tword_m takes a floating point division and multiplication, and conversion from float to long. I'd be surprised if it could complete in 32 us, or about 500 CPU cycles. A quick test suggests that it might take about 44 us to make the calculation - too long to avoid missing an interrupt. The guys at the Academy of Media Arts in Cologne may have overlooked this problem when they wrote their program, since they only recalculated once per second, instead of 25 times like your program does. There's no point in suspending interrupts to do an interruptible calculation. To avoid the problem, you can move the calculation out of the sensitive zone - calculate the tuning word and store it in a temporary variable, disable the interrupt, copy the tuning word to the active variable, and reenable the interrupt. Like this: unsigned long tword_t; // temporary variable for tuning word
tword_t = pow(2,32) * dfreq / refclk; cbi (TIMSK2,TOIE2); // disble Timer2 Interrupt tword_m = tword_t; sbi (TIMSK2,TOIE2); // enable Timer2 Interrupt
That leaves the slow calculation where it can be interrupted, and only requires a few cycles while interrupts are disabled to complete the assignment. If the calculation happens while the interrupt is disabled, that makes for substantial phase jitter happening 25 times per second - likely to be audible. Serial.println doesn't output anything, the serial monitor is scrolling but nothing appears Again, no surprise. Your baud rate is 9600; at that speed it takes nearly a millisecond to print a single character. Your tuning word is quite long. If you try to print it every 40 ms, as your code indicates, the printing operation won't be able to keep up. If you try to print from the ISR, you'll be printing something every 32 us, and that's way too fast. Pick a much higher baud rate, and print less often. And, as has already been said, it's a lousy idea to print from an ISR. Finally, consider how quickly your input value may be changing. if it can move very far in 40 ms, you might consider sampling less often, or mayby you'd prefer to digitally filter the analog reading.
|
|
|
|
|
17
|
Products / Arduino Due / Re: Problem compile blink file in linux
|
on: February 05, 2013, 03:15:32 pm
|
|
Installing the package, "ia32-libs" fixed this problem on my Ubuntu 12.10 64-bit system. Apparently, the files referenced by this error message are 32-bit executables, and won't run on a 64-bit system without help.
For my setup, Michael Meissner was right when he said, "... you don't have the proper libraries ..."
|
|
|
|
|
18
|
Topics / Robotics / Re: Sensing tilt using accelerometer alone
|
on: January 10, 2013, 05:27:36 pm
|
Here's a link that might give you some insight into how it's done in smart phones: http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf. It appears to be a bit more complex than what's been described so far, but maybe not a whole lot more complex. In particular, for any particular orientation of the accelerometer, there are two different values of pitch and roll that could describe the device's orientation, depending on whether you treat it as pitch followed by roll, or as roll followed by pitch. You'll find some general formulas. You'll also find a discussion of how a phone selects between portrait and landscape modes, which seems to be what you wanted in the first place. It looks to be a lot simpler than determining precise values for pitch and roll.
|
|
|
|
|
19
|
Using Arduino / LEDs and Multiplexing / Re: Flying LED matrix
|
on: December 15, 2012, 09:48:56 pm
|
Your text description suggests that you plan to use zero-based indexing, but your picture doesn't show an LED zero. Your first LED appears to be numbered as "1." So, your description of how you intend to address the spokes and rings doesn't match the numbering on the photograph. I'll presume that you intend for the LED marked as "1" to be LED "0," and that the numbers shown for all the other LEDs are higher than the address that you intend to use by 1. I don't see that an array implementation is necessary for what you want to do. There seems to be enough symmetry for an address calculation to work: - Even-numbered spokes have these LED addresses: 6*n + k, for even integer 0 <= n < 64, and integer 0 <= k < 6.
- Odd numbered spokes have these LED addresses: 6*n + 5 - k, for odd integer 0 <= n < 64, and integer 0 <= k < 6.
- Expressed in these forms, the LED address advances outward for increasing k. It's handy to express them in that fashion, since we'll want the addresses to progress in the same direction when we illuminate rings.
Using that information to calculate an LED's address, knowing its ring and spoke: int LED_Address(int spoke, int ring) { if (spoke & 1) { return(6*spoke + 5 - ring); } else { return(6*spoke + ring); } } This project might be a bit complex as a first foray into using arrays. Unless you're confident in your ability to address and control the LEDs, it'll be difficult to tell the difference between program issues and hardware interface problems. Simple programming exercises using arrays are abundant on the web - google "c arrays exercises" to find a gazillion of them. I'd recommend starting with something simpler, like outputting values to the screen, until you feel like you understand the concept and the techniques. It won't take long.
|
|
|
|
|
20
|
Using Arduino / Programming Questions / Re: Signed number grief.
|
on: November 12, 2012, 10:36:49 pm
|
That's not the mask I wanted. I wanted this one: const long deviceMask = -(1 << (deviceWordLength - 1)); The mask isolates the sign bit for testing, and extends the sign bit when the sign bit is set. It needs to be as long as the type of the input, which is int in this case, but it doesn't need to be longer.
|
|
|
|
|
21
|
Using Arduino / Programming Questions / Re: Signed number grief.
|
on: November 12, 2012, 07:46:00 pm
|
Having reflected a bit more on this, I see that in this code: const long deviceBits = 10; const long deviceWordLength = 16; const long deviceMask = (1 << deviceBits) - 1; there's no need for any of the constants to be declared long. The counting constants, describing length of the significant data and length of the word it resides in, can obviously be byte-sized, at least until we start using 257-bit integers. The mask doesn't need to be any bigger than the input data word, in this case int. Hmmph.
|
|
|
|
|
22
|
Using Arduino / Programming Questions / Re: Signed number grief.
|
on: November 12, 2012, 11:50:18 am
|
A slow imprecise floating point divide to replace a fast precise bit shift. I think the poster refers to this line: someFloatVariable = x * (deviceScaleFactor * (1.0/(1 << (deviceWordLength-deviceBits)))); Looking at these concerns one by one, in reverse order: - floating point divide: Indeed, there's a floating point division explicitly coded in that line. But, the arguments are all constants, along with everything else inside the parentheses. Based on the explorations of compiler's output for other complicated floating point expressions, I believe that the compiler will detect that the expression evaluates to a constant, optimize the internal calculations out of existence, and wind up with a single floating point constant. I don't see that there will be a division in the executed code.
- imprecise: I don't think so. The operation that's being replaced is a bit shift right, equivalent to division by 2N, for an integer N. The floating point representation of 2-N is a sign bit, an exponent, an implied one, and 24 zeroes. Division will result in a change of exponent only, and won't result in any loss of precision. It's true that, in general, precision is lost in a floating point division, but not in this case, and that's a not consequence of the particular parameters of this calculation, but rather of the very operation that's being performed.
- slow: Yes, a floating point division is slow. But, because everything involved is a constant, it happens at compile time, rather than at runtime. The Arduino won't execute a floating point division based on this code.
If you're skeptical about the compiler optimizing away the division, you can force it like this: ... const float deviceScaleFactorComplete = deviceScaleFactor * (1.0/(1 << (deviceWordLength-deviceBits))); ... someFloatVariable = x * deviceScaleFactorComplete; ... just trying to turn a 10-bit value into 16 ... Yes. But, the OP expressed concern about the fact that some of the proposed techniques rely on the fact that an integer has a 16-bit representation - an implementation-dependent size - and wanted to know how to make his code more general. That concern is of more than merely academic interest, because "on the Arduino Due, an int stores a 32-bit (4-byte) value." See it here: http://arduino.cc/en/Reference/Int. It's not at all unlikely that some of us will be porting code we write today to that platform, so there's certainly value in coding for the general case. ... load up the 10 bits into a 16-bit int and extend (copy) the sign in bit 9 from bit 10 to bit 15 ... It's even easier than that. The device provides a 10-bit signed number, left-justified in a 16-bit word. For a 16-bit platform, it's as simple as loading the value into a signed int, and shifting it six bits to the right; the sign bit is automatically extended. But that's not what the OP asked for: he asked for help in writing code that could easily accommodate a different number of significant bits from the input device, and he expressed concern about algorithms that relied on a 16-bit integer size. Because the issue has practical implications, it's getting a bit of attention. It's certainly made me wonder how deeply I've embedded implementation-dependent parameters into some of my own favorite code.
|
|
|
|
|
23
|
Using Arduino / Programming Questions / Re: Signed number grief.
|
on: November 11, 2012, 10:17:10 pm
|
I don't see how this helps: typedef long device_t; ... const device_t deviceWordLength = sizeof(device_t)<<2;
deviceWordLength is a characteristic of the input device. You can call it the length of the device's reply, or you can call it the position of the reply's sign bit. In this code, it depends only on the characteristics of the long data type. What am I missing?
|
|
|
|
|
24
|
Using Arduino / Programming Questions / Re: Signed number grief.
|
on: November 11, 2012, 11:56:17 am
|
Rethinking my earlier post about dealing with a left-justified, less-than-16-bit signed integer: you want a general method of managing that value. Specifically, you want something that doesn't rely on the size of an integer for any particular platform. Not a bad idea, if you want to be able to port an application to the Arduino Due, with its 32-bit integers. If you want that particular generality - if that's not an oxymoron - I don't see a way to avoid examining the sign bit, and then doing something to the data. You can do that as described previously in this post: I'll note that you can avoid the 6-bit shift by folding the shift operation into the floating-point multiplication, like this: const long deviceBits = 10; const long deviceWordLength = 16; const long deviceMask = -(1 << (deviceWordLength - 1)); const float deviceScaleFactor = 0.25; int x; ... if (x & deviceMask) { x |= deviceMask; } someFloatVariable = x * (deviceScaleFactor * (1.0/(1 << (deviceWordLength-deviceBits)))); It has the same advantages as the version in the post referenced above. I think - but don't know - that it will eliminate the 6-bit shift from the compiled code, because the compiler will recognize the factor in the last statement as being composed entirely of constants, and will do that calculation at compile time. It adds a characteristic of the sensor to the code - 0.25 degrees C per tick - but that was already embedded in the program, and it might as well be at the top where it's easy to find and modify. It also adds the characteristic that the device output is a 16-bit word. I've tested that code with the characteristics of the device described, and I think it works. I haven't tested it with other characteristics to verify its general-ness. Using the stimmer-fungus technique described above, the general code might look like this: const long deviceBits = 10; const long deviceWordLength = 16; const long deviceMask = (1 << deviceBits) - 1; const float deviceScaleFactor = 0.25; int x; ... x >>= (deviceWordLength-deviceBits); x += 1 << (deviceBits - 1); x &= deviceMask; x -= 1 << (deviceBits - 1); someFloatVariable = x * deviceScaleFactor; That code works in the specific case, too. It's not checked for generality. For more complete generality, you could add a const someType deviceOffset, to manage gizmos whose output values aren't centered on zero. That might be the input code that corresponds to a zero reading, in which case the constant would be int and added to x, or it might be the reading that a zero input describes, in which case the constant would be float and added to someFloatVariable. Then, with just a couple of value changes to constants, you could get your readings in, say, Kelvin, or - oh joy of joys - Farenheit or Rankine; or, you could get your readings from an analog conversion on something like a 4-20mA temperature transducer, or a single-supply LM35 circuit.
|
|
|
|
|
25
|
Using Arduino / Programming Questions / Re: Signed number grief.
|
on: November 11, 2012, 01:56:30 am
|
I'm wondering... since the high byte has the sign bit as bit 7, could I do the signed conversion THERE before I slide everything down? I've been racking my brain on this and I'm just not seeing it... I KNOW it must be simple but I just don't see it.
It may be even simpler than you think. From the Arduino Refrence page describing the bitshift operators at http://arduino.cc/en/Reference/Bitshift: When you shift x right by y bits (x >> y), and the highest bit in x is a 1, the behavior depends on the exact data type of x. If x is of type int, the highest bit is the sign bit, determining whether x is negative or not, as we have discussed above. In that case, the sign bit is copied into lower bits, for esoteric historical reasons... For your program, x is indeed of type int. You're starting with the sign bit in the MSB. Based on this snippet of the reference, all you have to do is shift the value to the right until it's scaled right, and the program will automatically extend the sign bit. Looks like it's done for more than historical reasons - with this behavior, we can divide a negative integer by 2 N by shifting right by N bits, just like we do for a positive integer. If x were declared as unsigned int, the sign bit wouldn't be extended, and zeroes would shift in at the MSB. Also - and this might be the best reason - when I tested your code, I found that this line x = (x & 0b0000001000000000) ? ((x & 0b0000000111111111) - 0b0000001000000000) : (x & 0b0000000111111111); // convert sign :( didn't have any effect. I got the same correct answers with it, and without it You might be overthinking this. Edit: Or maybe not. After reflection, I recall that you want a general solution that doesn't rely on a 16-bit length for an integer. The method shown in this post relies on that, since it relies on the fact that the sign bit is in the MSB. Back to the drawing board for me.
|
|
|
|
|
26
|
Using Arduino / Programming Questions / Re: Signed number grief.
|
on: November 11, 2012, 01:29:51 am
|
Another thing I don't like about my method is that it's not "generic". If the range of numbers had more or less bits, the above code would fail.
I don't see a way to make the code completely "generic," as you'd say, or "general," as I'd prefer to say. There's no way for the program to divine the number of bits that the input device provides - you have to tell it that number somewhere. Here's my favorite way to do it: const long deviceBits = 10; const long deviceMask = -(1 << (deviceBits - 1)); int x; ... if (x & deviceMask) { x |= deviceMask; } someFloatVariable = x; Here's why I like it: - There's only one place to describe the sensor input, and it's easy to find, and easy to determine what number to use
- It works whenever the input device provides something that's not bigger than a long
- It works for an int sized at something other than two bytes - it just has to be no bigger than a long
- The compiler remembers and uses - but doesn't need to allocate memory for - the constants
|
|
|
|
|
27
|
Using Arduino / Programming Questions / Re: Charliplexing Code without Library
|
on: November 09, 2012, 11:11:06 pm
|
So would it be better for me to learn charlieplexing using something like the LoL Shield?
It would be better to learn charlieplexing by understanding its underlying principles. Based on what you say in your posts, you seem to be confusing a charlieplexed array with an LED matrix. Maybe a matrix was what you intended to use? In a matrix arrangement, the canonical method is to drive a column pin to its active state, leaving all the other column pins inactive, and then drive the row pins of the LEDs you intend to light to their active state, illuminating some of the LEDs in a single column simultaneously. Naturally, the roles of the rows and columns can be exchanged, and maybe you want to illuminate only one LED at a time - if one of those is what you want to do, then your code just needs to reflect it. In a charliplexed arrangement, only one LED is illuminated at a time. The pin connected to that LED's anode is driven high, the pin connected to its anode is driven low, and all of the other pins are configured as inputs. The wiring is a lot more complex than a a matrix scheme - and, for all but a few trivial applications, the code is a whole lot more complex - and there's often not a natural one-to-one correspondence between a particular LED's location in the display and the pins that activate it. But, it'll address more LEDs than a matrix arrangement with the same number of pins. The explanation of how charlieplexing works is long and complicated; I'm not inclined to reproduce it here, since I'm not entirely sure that charlieplexing is what you intended, and it's already described in many places on the Internet. I'll suggest the Wikipedia article on charlieplexing, and the resources that it references. There are oodles of descriptions of LED matrix arrangements on the web; google away.
|
|
|
|
|
30
|
Using Arduino / General Electronics / Re: Nice, I just bought myself 2 Super Capacitors for $18 bucks + P&P
|
on: October 24, 2012, 12:02:50 am
|
For a capacitor, the rate of change of the voltage is equal to the current divided by the capacitance: dv i ---- = --- dt C For a constant current, the voltage changes at a constant rate. Two 150F capacitors in series will have a capacitance of 75F. For a current of, say, 30 mA, the rate of change of the voltage will be 0.03/75, or 0.4 mV / s. If the series combination of the capacitors is charged to its limit, 5.4V, and the critical voltage is, say, 4.5V, it'll hit that voltage in (5.4 - 4.5) / 0.0004 = 2250 s, or 37 1/2 minutes. Taking the positive terminal as the terminal that's, well, more positive, and the direction of current as out of the capacitor, the general formula for the time it takes a capacitor to discharge from an initial voltage Vi to a final voltage Vf is: i * t ( Vi - Vf ) = -------- C
and that resolves to: ( Vi - Vf ) * C ------------------ = t i The same formula applies for charging the capacitors - Vf is bigger than Vi, making the voltage term negative, and the current goes into the capacitor, making i negative, so the quotient is positive. Using the formula, it takes 75 amp-seconds for each volt of charging. At 1/2 amp, it'll take thirteen and a half minutes to charge the capacitors from a fully discharged state to 5.4V. It'll take nearly two and a half minutes to get it from 4.5V to 5.4V at 1/2 amp. Directly answering the question: But how long is 2 150F cap's in Series giving a little over 5v going to power a standard Arduino Uno? Translating "a little more than 5V" to, "exactly 5V," and adding the notion that the capacitors start at 5.4V, the answer comes to ( 30 / ( Arduino supply current in amps ) ) seconds. I don't find any really credible estimates for the supply current of the UNO, but I'll guess that it's about 30 mA, making the time come to a neat 1000 seconds, nearly 17 minutes.
|
|
|
|
|