Loading...
  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.


Code:
void setup() {
  Serial.begin(9600);
}

unsigned long MyValue=4294967290 ;

void loop() {
  MyValue=MyValue+1;
  Serial.println(MyValue,DEC);
  delay(100);
}


And the output:

Code:
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.

Code:
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.

Code:
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
Quote
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/733

Read 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.

Code:
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.
35  Forum 2005-2010 (read only) / Interfacing / Re: Reading Arduino data with C++ program on: December 02, 2010, 12:27:19 pm
Can you post a sample of the (incorrect) data received by your C++ program?
36  Forum 2005-2010 (read only) / Interfacing / Re: Basic software architecture for LED on: November 25, 2010, 11:59:12 am
Quote
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.
38  Forum 2005-2010 (read only) / Interfacing / Re: Visual Basic for Arduino on: November 19, 2010, 11:56:48 am
To se it to com14, just set
Code:
form1.MSComm1.CommPort=14
.
39  Forum 2005-2010 (read only) / Interfacing / Re: Visual Basic for Arduino on: November 19, 2010, 11:54:02 am
The MSComm control is a "component" that you need to add to your toolbar.  In my version of VB, it's under the Project --> Components menu.
40  Forum 2005-2010 (read only) / Interfacing / Re: Visual Basic for Arduino on: November 18, 2010, 01:22:33 pm
Throw a MSComm control on the VB form, set the properties for the MSComm to 9600,8,n,1.  Add code to the vertical scrollbar for change() to send serial data.

ie:  
Code:
form1.MSComm1.OUTPUT=str(form1.vscroll1.value)
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.
43  Forum 2005-2010 (read only) / Interfacing / Re: Arduino Web Server on: November 04, 2010, 06:13:54 pm
http://arduino.cc/en/Main/ArduinoEthernetShield

The first paragraph confirms 4 simultanious socket connections.

True, you only have 2KB of ram in which to store the page, but it could be stored in program memory too... up to 32KB that way.  But if you're really wanting to display much more than that, you can get an SPI ram chip, or an SD card.
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.
Pages: 1 2 [3] 4 5 6