Show Posts
Pages: [1] 2
1  Forum 2005-2010 (read only) / Syntax & Programs / help: on arduino serial parsing on: November 08, 2007, 10:51:17 am
IGnore me. Twas a stupid mistake. groan


2  Forum 2005-2010 (read only) / Syntax & Programs / parse serial packet on: July 17, 2007, 05:24:40 am
Hi,
This is something Ive been having issues with and wondered if someone could help. I simply want to control the pwm duty cycle on pin 9 and 10 from Pure data. One idea I had is i will send 3 bytes to the arduino

pwm1, pwm2, end_signifier

Ill use 255 for end signifier (dont mind loosing one value for the pwm).

What would the set up of serial.read and serial.available look like for this. If anyone could point me I'd be super grateful. Do i need to set up some kind of buffer?
Thanks
Nicky
3  Forum 2005-2010 (read only) / Syntax & Programs / Re: Arduino BT datarate on: April 06, 2007, 04:16:40 am
yip, very happy with this. 4 channels at 1kHz too which is cool. The limitation on sampling rate now comes from my code for sample and send. It cant execute 6 analog reads and the serial sending in under a ms so i miss an interupt which drops me to 500hz. Any sugggestions on how i might stream line my code would be welcome. perhaps its time to go and learn some asm.
4  Forum 2005-2010 (read only) / Syntax & Programs / Re: Arduino BT datarate on: April 05, 2007, 08:26:48 am
Hi,
Success! 6 channels at 500 samples per second 10bit resolution. I just put a delay of 30 seconds at the end of my setup. When max opens the serial connection there is no data for a few seconds and then it comes. It doesnt suffer from the problem i outlined with the ftdi serial here either http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1170939903/0

My firmware is based on firmata but smalller as im only reading the analog ins and with an interrupt (from the clock example changed slightly got atmega168) to time the sampling.
Code:
#include <avr/interrupt.h>
#include <avr/io.h>

#define INIT_TIMER_COUNT 6
#define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT


int int_counter = 0;
volatile int count = 149;
int oldcount = 0;



int analogPin = 0;
int analogInputsEnabled = 6;
int analogData;            // outgoing ADC value








// Arduino runs at 16 Mhz, so we have 1000 Overflows per second...
// 1/ ((16000000 / 64) / 256) = 1 / 1000
ISR(TIMER2_OVF_vect) {
  RESET_TIMER2;
  int_counter += 1;
  
  if (int_counter == 1) //set sampling frequency here 1 = 1kHz, 2 = 500Hz etc
  {
    if (count == 250){count = 149;}
    count+=1;
    int_counter = 0;
  }
};

void setup() {


  Serial.begin(115200);        // connect to the serial port

 
  //set up the timer 2 interrupt
  //Timer2 Settings: Timer Prescaler /64,
  TCCR2A |= (1<<CS22);    
  TCCR2A &= ~((1<<CS21) | (1<<CS20));    
  // Use normal mode
  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));  
  // Use internal clock - external clock not used in Arduino
  ASSR |= (0<<AS2);
  //Timer2 Overflow Interrupt Enable
  TIMSK2 |= (1<<TOIE2) | (0<<OCIE2A);  
  RESET_TIMER2;              
  sei();
  
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);          
delay(100);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(10000); //big delay to give time to establish serial link with max/pd whatever
digitalWrite(13, HIGH);  

}

void loop() {


            
  if (oldcount != count) {
   /* get analog in, for the number enabled */
      for(analogPin=0; analogPin<analogInputsEnabled; ++analogPin)
      {
            analogData = analogRead(analogPin);
                Serial.print(analogData >> 7, BYTE);
            Serial.print(analogData % 128, BYTE);

      }

Serial.print(255, BYTE); // end of analogs signifier  
 oldcount = count;
  }
  
}

5  Forum 2005-2010 (read only) / Syntax & Programs / Re: Arduino BT datarate on: April 05, 2007, 03:19:27 am
not sure if its realistic but the iwap manual claims data rates of 600kbps. Thats roughly 60kBps. my packet (arduino side) is 5 bytes. So that should be 12000 packets a second. OF course im ignoring the overhead from the bluetooth which i have no idea about.

I can handle latency as long as i get my rate so i wonder can i set the packet size so the blue giga buffers a few 5 byte packets and sends them together?

At the atmega to bluegiga end of things i reckoned that
At 115,200bps => 11,520 Bytes per sec. at 5 bytes a sample => 2304 samples per sec.

I'll investigate and report back. ANy info from folks in the know opn this stuff would be great.

thanks
Nicky
6  Forum 2005-2010 (read only) / Syntax & Programs / Re: Arduino BT datarate on: April 04, 2007, 04:34:47 pm
imac core 2 duo. Its really very oddd. havent looked at arduino2max as i really need > 500Hz sampling rate so im sending the 2 analogs in a  5 byte packet.
thanks
Nicky
7  Forum 2005-2010 (read only) / Syntax & Programs / Arduino BT datarate on: April 04, 2007, 04:11:28 pm
Hi,
Ive just started messing with an arduino BT. I am trying to sample 2 analog Ins at different sampling rates. It seems I can only sample at up to 15hz. ANy faster and the hardware serial monitor in the ide throws up a load of errors when trying to access the serial port. As if the port isnt available anymore. Same thing in MAX. At 10Hz max  serial happily opens the port and in comes the data. At higher sampling rate max says 'error cant open serial port bla bla bla'
Any ideas on where i could be going wrong?
I dont have the device here now but Im wondering is it that i am swamping the blugiga with too much data from the atmega168 side before it is properly connected to the computer/max?
Im going to try a long delay before i start sampling tomorrow to see if that helps but if anyone had example code that gives them a faster sampling rate Id be really grateful.
Will report back in the morning.
Thanks
Nicky
8  Forum 2005-2010 (read only) / Interfacing / Re: fast serial sendin on: February 28, 2008, 05:40:37 am
Hi,
How fast are you sampling and how much data are you sending? The easiest way to reduce the burstyness is to reduce the sampling rate so your datarate doesnt exceed the threshold that causes it to be sent in 4k blocks.
The hardware solution I posted is really very simple. All you need is a soldering iron and a bit of wire and a bit of solder. Or ask someone else to do the soldering. Just attach about a 2 inch piece of hookup wire to x3 pad 1 on the arduino. X3 is the  set of 4 connections beside the ftdi chip on your arduino. TO attach a wire I simply put a very small amout of solder on the iron. I then touched this against the back of pad 1 and pushed in the bit of wire from the front into the melted solder.
Now connect the other end of the wire into one of your digital pin sockets and in your code toggle this pin each time you want to send data up to PC/flash. In my example youll seee I digitalWrite(13, HIGH) before reading my inputs and then digitalWrite(13, LOW) after. This solution gave me much smoother data in MAX/MSP.
Let me know if you need photos and I'll try and put up some.
Nicky

 
9  Forum 2005-2010 (read only) / Interfacing / Re: fast serial sendin on: June 19, 2007, 12:09:19 pm
Heres a solution to the 4K block problem outlined in this topic. Solder a wire to X3 pad 1 on the arduino. This is the CTS pin on the ftdi chip. Toggling this pin will cause the ftdi to flush its send buffer up to the PC. Works like a charm. I connected this to pin 13 and set pin 13 high after a read through the analogues and low while waiting for an interrupt. Nasty. Can someone show me a really quick way to toggle each time throug the loop in hardly any code?

this code is now a complete mess but i'll clear it up later.

Mellis: I guess thats a use for X3  smiley

Code:
#include <avr/interrupt.h>
#include <avr/io.h>

#define INIT_TIMER_COUNT 6
#define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT

volatile int Ft = 1;
int int_counter = 0;
volatile int count = 149;
int oldcount = 0;
long starttime = 0;
long time;
long start;

int ledPin = 13;
int analogPin = 0;
int analogInputsEnabled = 4;
int i;
int analogData;            // outgoing ADC value
int n = 0; //index for digital read loop
int digitalPin;

byte x = 0; //byte to store digital pin status


// Arduino runs at 16 Mhz, so we have 1000 Overflows per second...
// 1/ ((16000000 / 64) / 256) = 1 / 1000
ISR(TIMER2_OVF_vect) {
  RESET_TIMER2;
  int_counter += 1;
  
  if (int_counter == 2) //set sampling frequency here 1 = 1kHz, 2 = 500Hz etc
  {
    if (count == 250){count = 149;}
    count+=1;
    int_counter = 0;
  }
};

void setup() {
  Serial.begin(115200); //setup serial
  Serial.flush();
  int resp = 0;
   pinMode(ledPin,OUTPUT);   // declare the LED's pin as output
  
  //set up the timer 2 interrupt
  //Timer2 Settings: Timer Prescaler /64,
  TCCR2A |= (1<<CS22);    
  TCCR2A &= ~((1<<CS21) | (1<<CS20));    
  // Use normal mode
  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));  
  // Use internal clock - external clock not used in Arduino
  ASSR |= (0<<AS2);
  //Timer2 Overflow Interrupt Enable
  TIMSK2 |= (1<<TOIE2) | (0<<OCIE2A);  
  RESET_TIMER2;              
  sei();
            
            
  //enable digital pullups
  for(i=2;i<8;++i)
                   {
                digitalPin = i;
                    digitalWrite(digitalPin, HIGH); //enable internal pullups
                    }


 digitalWrite(ledPin, LOW);


}

void loop() { start = millis();

  digitalWrite(13, LOW);  
  if (oldcount != count) {
   /* get analog in, for the number enabled */
      for(analogPin=0; analogPin<analogInputsEnabled; ++analogPin)
      {
            analogData = analogRead(analogPin);
                Serial.print(analogData >> 7, BYTE); // shift high bits into output byte
            Serial.print(analogData % 128, BYTE); // mod by 128 for the small byte

      }

Serial.print(255, BYTE); // end of analogs signifier  
                
                
//digital pin checking stuff
               x = PIND >> 2;
             Serial.print(x, BYTE);
               Serial.print(count, BYTE); // a counter that runs from 150 to 250 to check for missing bytes
               Serial.print(254, BYTE); // end of digital signifier
                  
    //a timer to see how long through the loop;
    time = (millis() - start);
    Serial.println(time);
                
              
      }
    
    oldcount = count;
    digitalWrite(13, HIGH);
  }

10  Forum 2005-2010 (read only) / Interfacing / Re: fast serial sendin on: April 06, 2007, 04:19:06 am
Just another point on this. I hadnt realised that ftdiport.inf is part of the driver download on windows. You must edit it before you install the driver on windows. I could find no equivalent on OS X though.
11  Forum 2005-2010 (read only) / Interfacing / Re: fast serial sendin on: April 04, 2007, 04:39:00 pm
nope nothing there. this must be a windows vibe only i guess
12  Forum 2005-2010 (read only) / Interfacing / Re: fast serial sendin on: April 04, 2007, 03:51:37 pm
Hi,
Im just returning to this issue again. Im mainly on OS X so im wondering what is the equivalent to the ftdiport.inf file? Or is there one? I might have a shot on my windows machine first to see if that helps.
Ill report back in a day or so.
Thanks for the pointers.
Nicky
13  Forum 2005-2010 (read only) / Interfacing / Re: fast serial sendin on: February 15, 2007, 11:15:28 am
okay. Ive been testing with sending data betweeen arduino and MAXmsp. I noticed that when i sample at 1000 samples persec the data stream becomes very bursty. In MAXMSp i can see i am receiving the data in 4KB chunks every 640ms. My data packet from the arduino is 6 bytes long. So that would be 6 * 8 * 1000 = 48000kbps. I believe the explanation lies here on page 8 http://www.ftdichip.com/Documents/AppNotes/AN232B-04_DataLatencyFlow.pdf

I dont have anymore time to spend on this but it looks like i need to recompile the ftdi driver with a lower USB block request size or something like that.

3.3 Effect of USB Buffer Size and the Latency Timer on Data
Throughput
An effect that is not immediately obvious is the way the size of the USB total packet request has on
the smoothness of data flow.  When a read request is sent to USB, the USB host controller will
continue to read 64 byte packets until one of the following conditions is met:
1. It has read the requested size (default is 4 Kbytes).
2. It has received a packet shorter than 64 bytes from the chip.
3. It has been cancelled.
While the host controller is waiting for one of the above conditions to occur, NO data is received by
our driver and hence the user's application.  The data, if there is any, is only finally transferred after
one of the above conditions has occurred.
Normally condition 3 will not occur so we will look at cases 1 and 2.  If 64 byte packets are
continually sent back to the host, then it will continue to read the data to match the block size
requested before it sends the block back to the driver.  If a small amount of data is sent, or the
data is sent slowly, then the latency timer will take over and send a short packet back to the host
which will terminate the read request.  The data that has been read so far is then passed on to the
users application via the FTDI driver.  This shows a relationship between the latency timer, the data
rate and when the data will become available to the user.  A condition can occur where if data is
passed into the FTDI chip at such a rate as to avoid the latency timer timing out, it can take a long
time between receiving data blocks.  This occurs because the host controller will see 64 byte
packets at the point just before the end of the latency period and will therefore continue to read the
data until it reaches the block size before it is passed back to the user's application.
The rate that causes this will be:
62 / Latency Timer    bytes/Second
(2 bytes per 64 byte packet are used for status)
For the default values: -
62 / 0.016 ~= 3875 bytes /second ~= 38.75 KBaud
Therefore if data is received at a rate of 3875 bytes per second (38.75 KBaud) or faster, then the
data will be subject to delays based on the requested USB block length.  If data is received at a
slower rate, then there will be less than 62 bytes (64 including our 2 status bytes) available after 16
milliseconds.  Therefore a short packet will occur, thus terminating the USB request and passing
the data back.  At the limit condition of 38.75 KBaud it will take approximately 1.06 seconds
between data buffers into the users application (assuming a 4Kbyte USB block request buffer size).
To get around this you can either increase the latency timer or reduce the USB block request.
Reducing the USB block request is the preferred method though a balance between the 2 may be
sought for optimum system response.
14  Forum 2005-2010 (read only) / Interfacing / Re: fast serial sendin on: February 13, 2007, 09:45:18 am
I'll have a look at lower baud but this looks like it may explain a further problem. In maxmsp the serial object gets no data for about 30ms and then 120bytes all at once. It gives very bursty and high latency at high datarates. I figured it was the serial object but perhaps it is related to this.
15  Forum 2005-2010 (read only) / Interfacing / Re: fast serial sendin on: February 08, 2007, 12:29:48 pm
Hi,
Kg4wsv thanks for the tips. I have baud at 115200. I commented out all the serial writes except for the timer one and no improvement. So i had a look in wiring.c where I found a delay(1); inserted in the code for analogread. Because Im cycling through the 6 analogues it adds up[ to 6ms to execute the reads. The comment says
// without a delay, we seem to read from the wrong channel

Ah well. I changes it to delayMicroseconds(200); and all seems fine.

Ill keep testing.
Pages: [1] 2