Pages: [1] 2   Go Down
Author Topic: Need help for fast (10bits) analogRead & serial TX  (Read 2488 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 13
Deicimila/Ubuntu/IDE 0012(64bits) & 0015(32bits)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello Everyone,
I'm trying to make a XY tube curve tracer project and need to send 2 (synchronous as possible) 10bits analogReads as fast as possible (using serial) to processing.
I'm also using a digitalWrite in the loop.

I don't know really where to start, if I understood correctly, it's better to split the analogReads 10 bits of data in 2 bytes (instead of 4 for an int) to speed up serial communication (and bandwidth).
Also the most important part to achieve is having the 2 analogReads (per loop) being within less than 1ms between each other, or synchronous if possible ?
Synchronous transmission of the data is not required, I can use a buffer or memory (I have an I2C chip).
Could someone help please, I'm totally ignorant regardint interrupts buffering or serial com, (should I use an external library ?)
Thanks a lot
Logged

Plus je pédale moins vite, moins j'avance plus vite ...

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26496
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

20 bits total, three bytes minimum, four if your bit-packing isn't up to spec.   smiley-wink
So, to transmit four bytes serially requires 4 * 10 bits = 40 bits.
40 bits in 1mS gives a minimum speed of 40000 bits per second.
Go for 57600.
« Last Edit: May 28, 2009, 06:27:12 am by AWOL » Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 13
Deicimila/Ubuntu/IDE 0012(64bits) & 0015(32bits)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In fact I should transmit two 0-1024 readings (that are as simultaneous in time as possible) to the sofware, 1ms between them being quite bad BTW), I think that if I "bit-pack" I have to add some kind of "separators" too?
And I'm confused with "bit packing" some example code would be appreciated !

PS: the data transmission could happen later, it has not to be real time nor synchronous, it can wait in a buffer or be stocked somewhere. the key here is short time between the 2  succesive analog readings of the loop (I can spend time between loops and pairs of readings).
I'm measuring 0 to 500V sine pulses (0 to 1024) that are 20ms long so few µs would be far better  !
Excuse my poor english please, I hope I'm clear.
« Last Edit: May 28, 2009, 07:29:20 am by bembel » Logged

Plus je pédale moins vite, moins j'avance plus vite ...

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26496
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I think that if I "bit-pack" I have to add some kind of "separators" too
No, because you'd always be packing two lots of ten bits.
Probably not worth the effort, anyway - it only saves you ten bit periods on the serial line.
So, instead of 40000 bps, you'd need 30000bps.
You may still need occasional sync points.

Analogue conversion rate is about 10kHz, so consecutive samples should be about 100uS (0.1mS) apart.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 13
Deicimila/Ubuntu/IDE 0012(64bits) & 0015(32bits)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Analogue conversion rate is about 10kHz, so consecutive samples should be about 100uS (0.1mS) apart.
thanks AWOL, I'm now able to calculate the error ratio.
I still can't figure out how convert int into 2 bytes then to spilt it & send data & merge in processing. (should I use an external library)
Maybe there is some typical protocole code I haven't found with google ?
thanks again, I'm more confortable with vacuum tubes  smiley-wink
« Last Edit: May 28, 2009, 10:03:59 am by bembel » Logged

Plus je pédale moins vite, moins j'avance plus vite ...

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26496
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I still can't figure out how convert int into 2 bytes then to spilt it & send data & merge in processing. (should I use an external library)

Something like:
Code:
unsigned short readingA = analogRead (apin);
unsigned short readingB = analogRead (bpin);
Serial.print (readingA >> 8, BYTE);
Serial.print (readingA & 0xFF, BYTE);
Serial.print (readingB >> 8, BYTE);
Serial.print (readingB & 0xFF, BYTE);

Voila
« Last Edit: May 28, 2009, 10:14:10 am by AWOL » Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 13
Deicimila/Ubuntu/IDE 0012(64bits) & 0015(32bits)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

merci beacoup !

I'll still need to merge it but it shouldn't be that hard ... is there an interest using interrupts (or a library like new software serial) for faster speed ?

thanks again
« Last Edit: May 28, 2009, 03:42:00 pm by bembel » Logged

Plus je pédale moins vite, moins j'avance plus vite ...

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 77
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Software serial is if anything going to be slower, because the hardware USART does a lot of things (like automatically generating start and stop bits) that the software serial library has to emulate in software.

For the timeframe of <1mS, you should be able to do everything with the default arduino functions with plenty of time left over.

Note also that you can set the serial baud rate faster than even the 115200baud listed as the max baud rate in the Arduino IDE.  I've set the baud rate to 250000 and still been able to send and receive with no errors, although I had to optimize the code pretty carefully in some places.  Not sure how well Processing will support those speeds, though.

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 13
Deicimila/Ubuntu/IDE 0012(64bits) &amp; 0015(32bits)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

After calculating the error ratio (sorry to be late), in fact, if I want the I/V curve to be < 1V precision (which is the purpose of such a device) with 500V peaks lasting 10mS (I'm stuck with mains frequency, 50 Hz here).
So I need a timeframe of 10µS (roughly a bit less than 0,5V resolution which correspond to the global horizontal Volts scale precision of 500V/1024).
I understand the limitation of the serial communication bandwidth but that's not an issue here, only the two reading per cycle have to be close each others and then do as many cycles as needed to have enough values to plot a nice curve.
I found two topics on this forum that let me think that it should be achievable but I'm a bit lost to implement the code.
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1242967991/2
(arduinoscope up to 360000 samples/sec)
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1242466935/8#8
improved serial communication

thank you for your help.

PS: I've manage 115200 Bauds com. between arduino & processing without problems.
And to recapitulate the only things needed in the loop are 2 close analogReads, 1 digitalWrite(that changes only, let's say every seconds) and occasional (if it can shorten the timeframe) TX of the data.
« Last Edit: May 29, 2009, 03:05:07 am by bembel » Logged

Plus je pédale moins vite, moins j'avance plus vite ...

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26496
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The two channel requirement is a bit a killer at these kind of speeds.
The 'scope presented above is a single channel device - the documentation for analogRead warns against switching sources too rapidly here:
http://arduino.cc/en/Tutorial/AnalogInputPins
in "Details and Caveats".
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 13
Deicimila/Ubuntu/IDE 0012(64bits) &amp; 0015(32bits)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The Atmega168 datasheet also cautions against switching analog pins in close temporal proximity to making A/D readings (analogRead) on other analog pins. This can cause electrical noise and introduce jitter in the analog system. It may be desirable, after manipulating analog pins (in digital mode), to add a short delay before using analogRead() to read other analog pins.

Doesn't it apply only to "switching" a pin from digital to analog ? (which is not my case)
« Last Edit: May 29, 2009, 04:43:28 am by bembel » Logged

Plus je pédale moins vite, moins j'avance plus vite ...

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26496
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmm, not sure now - I assumed it referred to switching the analogue input mux to the A/D converter.
I'll have to check the datasheet.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 13
Deicimila/Ubuntu/IDE 0012(64bits) &amp; 0015(32bits)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So far I've tried a standart arduin-o-scope sketch with 6 analogReads in a for loop like (i=0, i<6, i++) analogread(i) without apparent noise.
Logged

Plus je pédale moins vite, moins j'avance plus vite ...

0
Offline Offline
Newbie
*
Karma: 0
Posts: 13
Deicimila/Ubuntu/IDE 0012(64bits) &amp; 0015(32bits)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I had a look to Port register in the documentation, and it says that:
Quote
the PIN register reads the state of INPUT pins set to input with pinMode()
...
PINB is the input register variable It will read all of the digital input pins at the same time.

Sometimes you might need to set multiple output pins at exactly the same time. Calling digitalWrite(10,HIGH); followed by digitalWrite(11,HIGH); will cause pin 10 to go HIGH several microseconds before pin 11, which may confuse certain time-sensitive external digital circuits you have hooked up. Alternatively, you could set both pins high at exactly the same moment in time using PORTB |= B1100;

Can I use these properties using PINC and achieve two analog readings at the same time or in less than 10µS ?
I don't clearely understand if PINC return the state of the pin (Input/Output) or its value (0-1024) ?

Thank you for your help.
Logged

Plus je pédale moins vite, moins j'avance plus vite ...

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Unfortunately you can't. Each analog value must be read separately.

Theoretically you could save a little time by using low level register functions instead of the Arduino analogRead function  But you would need to study and understand the low level register functions documented in the ATmega datasheet to get this to work and its probably not worth the trouble because you would not get anywhere near the improvement that you get with direct port io compared to digitalRead..
« Last Edit: May 31, 2009, 03:27:24 am by mem » Logged

Pages: [1] 2   Go Up
Jump to: