Show Posts
|
|
Pages: 1 2 [3] 4 5 6
|
|
31
|
Forum 2005-2010 (read only) / Syntax & Programs / Re: maximum duration of unsigned long
|
on: November 17, 2010, 02:55:20 pm
|
You can easily test the behavior of the overflow. I started near the max unsigned long value so it wouldn't take long. void setup() { Serial.begin(9600); }
unsigned long MyValue=4294967290 ;
void loop() { MyValue=MyValue+1; Serial.println(MyValue,DEC); delay(100); } And the output: 4294967292 4294967293 4294967294 4294967295 0 1 2 3 4 5 The result makes sense. Any byte value can range from 00'x fo FF'x. So if you add 1 to FF'x, it becomes 100'x, but that won't fit into a single byte, so we consider it overflow. The most significant digit is truncated. so you're left with 00'x. Overflows of unsigned integers behave this way. They behave exactly the opposite for underflow. It wraps from 00'x to FF'x. Now, with signed integers, it's a bit more complicated because the numbers are stored in 2's compliment. (You'll only notice a difference for negative numbers). The signed variable stores the same number of total values as an unsigned variable does, but they range from -x to +x intead of the unsigned range of 0 to +2x. When the signed integer overflows, it's essentially turning on the sign bit. The only way to detect a signed integer overflow is to take the signs of both operands and compare them to the sign of the result. Positive + Positive = Positive Positive + Negative = Either, depending on the magnitude of the operands. Negative + Negative = Negative Negative + Positive = Either, depending on the magnitude of the operands.
In your case, When micros() overflows, it resets to zero. timecount=micros() - startTime; When you run your program, it will look like timecount increases from zero to 4294967295-startTime. At which point mills() overflows and resets to zero. Zero-startTime underflows and results in a large number. So timecount appears to keep counting upward until it reaches it's max value of 4294967295 and resets to zero. At the point that timecount resets to zero, mills() = startTime again. Once mills() is greater than startTime again, it will act as it did when it first started. Essentially, it will loop from 0 to 4294967295 counting up over and over again.
|
|
|
|
|
32
|
Forum 2005-2010 (read only) / Interfacing / Re: 7-Segment Display Wiring and Programming
|
on: December 08, 2010, 05:25:12 pm
|
How would I wire it with a shift register and which should I use? Here's a shift register from Sparkfun... costs about $1.50 http://www.sparkfun.com/products/733Read the datasheet on it and it will explain how to use it. Basically, you connect it to the serial connection on your board, and then supply it with power and ground. Each time you send a byte on the serial connection, it shifts it into the register (1 byte = 8 bits). Until you send it another byte, those 8 bits will remain set. So, you just send a byte representing the digital outputs you want to turn on/off. Hex Binary 0xFF = 11111111 This turns all 8 outputs of the shift register on. 0x00 = 00000000 This turns all 8 outputs of the shift register off. 0xAA = 10101010 This turns every-other output on.
So, now, all you have to do is connect each of the 8 shift register outputs to one of the segments on your display. (Remember to connect the display to ground as well.)
|
|
|
|
|
33
|
Forum 2005-2010 (read only) / Interfacing / Re: 7-Segment Display Wiring and Programming
|
on: December 06, 2010, 03:43:53 pm
|
|
7 Segment displays are fairly easy.
You'll need 7 I/O pins for each digit if you do it without an additional components.
Otherwise, pick up a shift register from Sparkfun. You can then drop the I/O requirements significantly.
The datasheet shows that each of the seven segments on the display are labeled as a,b,c,d,e,f,g and dp (decimal point). Apply a voltage to pin 1 or 5, and the apply a voltage to the pin for the segment which you want to turn on. Pretty easy.
The trickier part will be wiring up your shift registers correctly, as you'll have a mess of wires for 8 digits (8x7 = 56 wires minimum).
You'll likely need to write some code that extracts a single decimal digit from an integer and figures out which display it goes on.
|
|
|
|
|
34
|
Forum 2005-2010 (read only) / Interfacing / Re: how to talk with VB and know the data?
|
on: December 01, 2010, 07:49:05 pm
|
|
Use the Mid() function in VB to extract the value you want from the string.
Remember that Visual Basic will interpret all incoming serial data to ASCII. You must be careful that if you want to send ASCII digits, use the print(range,DEC). That may be the default for integers and doubles, but it won't be for anything stored in raw BYTE data.
|
|
|
|
|
36
|
Forum 2005-2010 (read only) / Interfacing / Re: Basic software architecture for LED
|
on: November 25, 2010, 11:59:12 am
|
What I'm not sure about is how quickly I'll need to sample in order to get a good idea of when the beat is. Depends on the sampling rate of the music you're listening to. Google "Nyquist Frequency". Basically, Nyquist says to only sample at 1/2 the frequency. If the music was converted to digital, then it's already been sampled, so there's no reason for checking more rapidly than the sampling of the music already. (ie: You won't get any more data resolution out of it... you start overlapping and only sample extra noise into the mix). If you're dealing with analog music, then check out the range of sampling that most mp3's are recorded at. 8khz is about as slow as music sampling goes. Any less than that, it sounds absolutely terrible. Most mp3's are sampled at 128kHz, I don't notice any improvement above that, although I'm not an audio professional. Read the wikipedia article, it's quite good.
|
|
|
|
|
37
|
Forum 2005-2010 (read only) / Interfacing / Re: Visual Basic, Firmata and Arduino
|
on: November 16, 2010, 06:45:21 pm
|
|
You'll have a large difficulty getting VB to upload code to the Arduino. Sending data and communicating with a sketch already uploaded to the board is quite easy. You need to put a MSComm control on your form. You'll find that in the list of components as "Microsoft Comm Control" Once you have that, it's quite easy, just read the MSDN about the Comm control if you don't see how to do it from there.
|
|
|
|
|
41
|
Forum 2005-2010 (read only) / Interfacing / Re: How to send a Linux EOF marker from Arduino
|
on: November 16, 2010, 06:42:06 pm
|
|
Part of the problem is that you're using the cat program to receive your data instead of writing your own program to do it. The cat program keeps control of the console thread until the program ends. Even if you send the EOF, until the cat program ends, it will not give the system back control.
What you should do is write a 'c' or java program that receives the data and saves them to a file. That way, you can send whatever character you want as an EOF marker, and tell your program to end or quit looping waiting for data. This can be done very easily on linux.
|
|
|
|
|
42
|
Forum 2005-2010 (read only) / Interfacing / Re: buffer in serial comm
|
on: November 05, 2010, 12:09:07 pm
|
Since the Serial protocol is byte oriented... it always must send a full byte of data; it can not send less or more at one time. If it needs to send two bytes, it sends one and then the other... serially, hence the name. A byte is 8 binary digits (0 or 1). A byte can also be represented as two hexidecimal digits (0 through F). So the maximum value that can be stored in a byte is 11111111 in binary, 255 in decimal, FF in Hex, or the character "ÿ" in ASCII. (a "y" with an umlat). Check out the ASCII table at http://www.ascii-code.com/. You'll notice that the values of the characters range from (Decimal) 0 to 255. The maximum ASCII value fits perfectly into a single byte. I'm sure the gods who created the first ASCII table did this on purpose. Then the UTF-8 gods came and destroyed them. (haha, that was a joke) Since PCs use the ASCII character set, and the Serial protocol is byte-oriented, naturally most PC programs interpret Serial data as ASCII. I'm sure that some programmer out there thought they were saving you a lot of trouble by doing that. I guess they assumed that Serial communication was generally going to be used for sending text (characters). On the Arduino side, however, you have the Serial.print() function which lets you specify if you want to transmit the BYTE, or DEC value which does the conversion to ASCII for you. The Serial.write() function does not... it always sends the BYTE value. With all that said, there are two issues with your code: 1. You declared your buffer[] array as an integer... which is a two-byte data type. That'll cause significant issues if you try to send that over serial. It will probably succeed, but it will split all of your integers into two bytes each, and you'll need to re-assemble the values on the other end. It will also only send half as much as you thought you were sending... only 50 integers would get sent. This was already pointed out by PaulS, and looks like you've fixed that. Strings are just buffers of the char data type (which happens to be a single-byte) so that will work nicely. 2. The thing you need to remember is that the data type really matters. If your buffer array is declared as integer, setting buffer[0]=65 sets two bytes: Byte1 Byte2 Binary: 00000000 01000001 Hex: 00 41 Since the value is not greater than 11111111 binary or FF hex, the high byte is set to zero. The character represented by a zero, chr(0), is null, which usually behaves badly for programmers. It is not zero, it is literally, nothing. It will not be displayed, it takes up no space. But if your buffer array is declared as BYTE, or char, then assigning buffer[0]=65, you're only setting a single byte (This is equivalent to buffer[0]='A'). Byte1 Binary: 01000001 Hex: 41 So, the character (or ASCII value) of 65="A". When you transmit that across, PCs interpret that as ASCII, not as a byte. Most programs will let you use an asc(<character>) function to return the decimal value of the character, and a chr(<number>) function to give you the ASCII character from a decimal value. A way you can get around this issue, is storing your numbers as characters (strings) and then parsing out the values on the PC end. So if you want to send the sensor's value 1023, you store it in a string as "1023". When you send the character buffer (length 4) across the serial connection, it sends: binary: 00110001001100000011001000110011 Hex: 31303233 Decimal: 49,48,50,51 ASCII: 1023 On the PC side, it will receive the string "1023" because it (usually) automatically assumes Serial data is ASCII. To re-assemble it to an integer value, you then parse the digits, or use a ValueOf(<string>) function like Java supplies. Another way to deal with this issue is to use the map() function in your Arduino code. The map function allows you to map a value range to another range. So, you can convert your sensor values (0-1023) to a byte range (0-255). This way, you can simply save the values as bytes and send them across. Then tell the PC to use the ASCII value Asc() instead of the character! Of course, re-mapping the value range to a smaller one causes a loss of resolution. It just depends what you need. A hack work around... quick and dirty... if you're just sending numbers 0 through 9, is to add decimal 48 to the integer value and save it as a byte. so: 0 +48 = 48. ASCII 48="0" 1 +48 = 49. ASCII 49="1" 2 +48 = 50. ASCII 50="2" 3 +48 = 51. ASCII 51="3" 4 +48 = 52. ASCII 52="4" ... you get the idea.
|
|
|
|
|
44
|
Forum 2005-2010 (read only) / Interfacing / Re: Arduino Web Server
|
on: November 02, 2010, 02:40:51 pm
|
|
The limit of traffic will be determined by the connection speed of the WiFi or ethernet and the speed of the microcontroller's CPU.
If you use a WiFi chip, you'll be limited to the 802.11 speed on the chip you buy. The WiFi chip I looked at bragged a "Host Data Rate Up to 100 Mbps for SDIO, 44 Mbps for SPI and 2.7 Mbps for UART"
Converted into comparable terms: SDIO = ~12 MegaBytes/sec SPI = ~5 MegaBytes/sec UART = ~330 KiloBytes/sec
Likewise for an ethernet shield. The ethernet shield I looked at supported 100BaseTX communication, so it can ideally provide 100Mbit/sec. (~12 MegaBytes / sec). However, like all things in the engineering world, the ideal is never the reality.
The microcontrollers commonly run at 16Mhz, so that may be a limitation if you have lots of web requests, but 16Mhz is plenty fast for processing most data.
Suppose for a moment that you reserve half of the CPU time for receiving and processing requests, and the other half of the time is used for transmitting data. I don't think that's terribly unreasonable.
8,000,000 hz = 8,000,000 cycles per second. If we suppose that sending one bit is a single-cycle operation, then you'd be able to send 8 Megabits per second (ie: 1,000,000 bytes / sec). That equates to 976 KiloBytes per second (1KB = 1024 Bytes).
If sending one bit is a two-cycle operation, then you can half the output, and you get 488 KB/sec.
Likewise, if sending a bit is a 4-cycle operation, you end up with 244 KB / sec.
Even with the worst case scenario, most ISPs aren't giving internet connections much better than 500 KB/sec unless you're paying through the nose for it. And even then, the rate is partly determined by the remote host... how fast is their ISP letting them transfer from you?
On average, you're probably looking at somewhere between 150 and 200 KB/sec for the run-of-the-mill internet connection, which it appears the microcontroller should be able to dish out fairly easily.
How much data are you planning on serving from the microcontroller? If you're serving a regular text HTML page, that's proabably 20 KiloBytes or less, so that would transfer very fast, even with several people requesting it at the same time. However, if you're hosting 100 KB - 500 KB pages, it might take a few seconds to load, and longer if you have multiple people accessing it.
|
|
|
|
|
45
|
Forum 2005-2010 (read only) / Interfacing / Re: Blink and Fade LED's at the same time
|
on: November 02, 2010, 02:53:01 pm
|
|
Sounds like you might want to use some interrupts here. You could set up an interrupt for blink, and a seperate one for fade. PaulS is correct though, if they blink or fade at different rates, it suddenly gets much more complicated.
Inside your interrupt service routine, you can count the number of overflows, and fade the LEDs based on the number of overflows it counts. That way, you'd be able to fade more than one LED using only a single interrupt. They'd still be linked though, so you're still limited somewhat. If you explain a bit further about how exactly you want them to blink and fade, we might be able to help you out a little better.
|
|
|
|
|