Show Posts
Pages: [1] 2 3
1  Using Arduino / Networking, Protocols, and Devices / Re: Problem Synchronizing micros() Between Two Arduinos on: December 23, 2013, 03:19:19 am
Tack - yep! That was it. The clocks were drifting. I got it to stay within 26 microseconds by syncing every 5 seconds.

For any future strugglers, here's a quick write up with code included: http://aaka.sh/patel/2013/12/23/synchronizing-micros-millis-arduino/

joshuabardwell - It seems possible! A quick search came up with promising results. I might try it one day!

Thanks all!
Aakash
2  Using Arduino / Networking, Protocols, and Devices / [SOLVED] Problem Synchronizing micros() Between Two Arduinos on: December 22, 2013, 02:44:09 am
Hey there -

I have a setup with three (3) Arduino Dues where I'm trying to synchronize the microsecond timestamps between two of them. In my current setup, I have a central "time server", which is booted up before all other Arduinos. This Arduino just responds with its own timestamp via I2C. The code is below.

The remaining two Arduinos are booted up sequentially (as not to crash on the I2C bus). Upon boot, each Arduino pings (via I2C) the time server Arduino and records the timestamp that the server reports. Then when a button is pressed on pin 10,  the Arduinos will print out via Serial the [time server timestamp + micros()] (the timestamp in the reference frame of the time server...or close enough). The code is below.

In my current test rig, I have both Arduinos connected to the same button. However, the timestamps are off. Here are a few timestamps after a lot of button presses:
Code:
ARDUINO 1 ARDUINO 2
SYNCING… SYNCING…
97987306 97987360
105037345 105037442
105196726 105196824
120266032 120266224
120357427 120357620
128765414 128765659
128918271 128918517
136696763 136697058
136950139 136950435
136960594 136960890
147941940 147942305
148092120 148092486
158248603 158249032
158454726 158455157
158464636 158465067
163082746 163083206
163189754 163190214
164674937 164675406
164811519 164811989
167329300 167329786
167424599 167425085
168005684 168006174
168155157 168155623
168581157 168581652
168687951 168688445
183834746 183835336
183981555 183982146
187934177 187934792
188088331 188088948
188949054 188949676
188958589 188959870
189129449 189130072
189617876 189618502
189807592 189808219

Notice how they're kinda close at the beginning, but as time goes on they're way off (in terms of microseconds... smiley-wink )

I'm not really sure how to tackle this and would appreciate any advice.

Thanks a lot!
Aakash

Time Server code:
Code:
#include <Wire.h>

String timeValue; // Variable to hold time

void setup()
{
  timeValue.reserve(10); // Reserve 10 bytes for unsigned long time
  Wire.begin(0x50); // Setup I2C slave address as 0x50    
  Wire.onRequest(requestEvent); // Register event
}

void loop() {
 // Do nothing
}

void requestEvent()
{
  timeValue = String(micros());  // convert timestamp to string
  volatile int timeLength = timeValue.length();  // find out how many digits are in the current time
  // If not 10 digits (max digit length for unsigned long), add leading zeros
  // This is to keep the time of I2C transfers consistent between subsequent read/writes
  if(timeLength == 1){
    timeValue = "000000000" + timeValue;
  }
  else if(timeLength == 2){
    timeValue = "00000000" + timeValue;
  }
  else if(timeLength == 3){
    timeValue = "0000000" + timeValue;
  }
  else if(timeLength == 4){
    timeValue = "000000" + timeValue;
  }
  else if(timeLength == 5){
    timeValue = "00000" + timeValue;
  }
  else if(timeLength == 6){
    timeValue = "0000" + timeValue;
  }
  else if(timeLength == 7){
    timeValue = "000" + timeValue;
  }
  else if(timeLength == 8){
    timeValue = "00" + timeValue;
  }
  else if(timeLength == 9){
    timeValue = "0" + timeValue;
  }
  Wire.print(timeValue); // respond with padded timestamp
}

Timer Sync code:
Code:
#include <Wire.h>

char dataFromTimeServer[10]; // char array to hold I2C data from TimeServer
unsigned long timeFromTimeServer = 0;  // unsigned long to hold time from TimeServer

unsigned long currentSyncedTime = 0;

const int buttonPin = 10;

void setup() {
  Serial.begin(9600);
  Serial.print("SYNCING...");
  syncTime(); // Sync time with TimeServer
  
  digitalWrite(buttonPin,HIGH);  // enable pull up resitor
  attachInterrupt(buttonPin, buttonPress, FALLING);  // register interrup on FALLING state
}


void loop() {
 if(currentSyncedTime!=0){
   Serial.println(currentSyncedTime);
   currentSyncedTime=0;
 }
}
// Run when falling
void buttonPress(){
  // Record timestamp in reference frame of TimeServer
  currentSyncedTime = timeFromTimeServer + micros();
}

// Method to read timestamp from central TimeServer over I2C
void syncTime(){
  Wire.begin();  // Initialize I2c
  
  Wire.requestFrom(0x50, 10);  // Request 10 bytes
  int index = 0;  // index of char array
  while(Wire.available())   // while more bytes avail
  {
    char c = Wire.read();    // receive a byte as character
    dataFromTimeServer[index++] = c;  // store byte in char array
    
  }
  timeFromTimeServer = atol(dataFromTimeServer);  // convert char array to unsigned long
  
}
3  Using Arduino / Interfacing w/ Software on the Computer / Re: Non-Standard Baud Rate Not Working on: September 29, 2013, 12:05:49 pm
Rob,

Here are the analyzer outputs you requested:

9600:

19200:

38400:

57600:

115200:

250000:

500000:


Thanks
Aakash

EDIT: Added 500k screenshot.

EDIT 2: After looking closely, I noticed that it took ~150 microseconds at 250k and ~120 microseconds at 500k. I didn't have a serial console attached during these tests. Why is there such a huge gap in time between each byte? Would buying the faster Due remedy this?
4  Using Arduino / Interfacing w/ Software on the Computer / Re: Non-Standard Baud Rate Not Working on: September 28, 2013, 01:59:05 pm
Rob,

The logic analyzer output looked great in all cases.

EDIT 1: Okay, so I tried using PuTTY on Windows inside of a VM and I got it to work at both 250000bps and 500000bps.

EDIT 2: I just tried with CoolTerm on OS X at 500000bps and it worked. Guess the screen command is just wonky.

So a question remains:

When measuring the loop-time at 250k and 500k using the sketch in my first post, they both got the same loop time (Around ~240-250 microseconds.) When adding more characters to each line [about 12 in total] and reading the state of a pin I get around 1100-1200 microseconds per loop in both (I measured that the logic, excluding the Serial.print(), takes around 240 microseconds). Why are these times the same?
More importantly, would using an Arduino Uno @ 16MHz improve these times dramatically?  What about the Arduino Due?

Thanks again!
Aakash
5  Using Arduino / Interfacing w/ Software on the Computer / Re: Non-Standard Baud Rate Not Working on: September 27, 2013, 05:07:49 pm
Rob,

Why isn't the logic analyzer able to decipher the bytes correctly and gives those errors on the higher baud rates?

Also, I'm connecting to the Arduino via a Macbook Air running OS X 10.8. The converter I'm using is this: https://www.sparkfun.com/products/9873
The board I'm using is this: https://www.sparkfun.com/products/10914
So, they're both 3.3v devices.

Thanks again for your help,
Aakash
6  Using Arduino / Interfacing w/ Software on the Computer / Re: Non-Standard Baud Rate Not Working on: September 27, 2013, 10:30:47 am
robtillaart - Okay, so I used a logic analyzer with the Arduino set to various baud rates (9600, 19200, 38400, 57600, and 250000bps)  and found something strange.

When using the following command on every test, excluding 250000, I was able to get "HELLO" printed repeatedly.
Code:
screen  /dev/tty.usbserial-A601EKZ6 <BAUDRATE>

The strange part is that the logic analyzer was only able successfully show correct data on 9600bps.  

Please see the attached files for the logic analyzer screenshot (excluding 19200, due to the attachment limit). The filenames correspond with the baud rate.

Is this a clock problem? If so, is my oscillator really *that* bad?

Thanks,
Aakash

Here's the code I used to test:
Code:
void setup(){

  Serial.begin(57600);
  Serial.println("---BASIC SERIAL TIMER APP INITIALIZED---");
}
void loop(){

      Serial.println("HELLO");

}
7  Using Arduino / Interfacing w/ Software on the Computer / Re: Non-Standard Baud Rate Not Working on: September 26, 2013, 05:47:30 pm
@robtillaart - Thanks for the suggestion! However, if I understand correctly, that will improve the performance of my current app at 57.6k. But, at that rate there is still a 3.5% error rate and the project I'm working will spit out a lot of data and needs to be accurate (it's for scientific data collection). The next lowest baud rate is 38.4k (0.2% error) and that's way too slow for my use as that 30 character figure I stated earlier might increase as I proceed with my project.

So my question remains - how can I get 250k baud rate working? I'm interested in the 500k baud rate as well (it has 0% error as well, according to the manual), but thought it would be wise to get the lower of the two rates working first.

Thanks a lot!
Aakash
8  Using Arduino / Interfacing w/ Software on the Computer / Non-Standard Baud Rate Not Working on: September 26, 2013, 03:03:59 pm
Hello,

I have an Arduino Pro (8MHz/m328/3.3v) and wanted to use a serial baud rate that's higher than 57.6k. I realize that 115.2k and 230.4k aren't going to work as the "error" is too high. So, I tried to use 250k, as it has a 0% error in accordance with page 202 of the manual: http://www.atmel.com/Images/doc8161.pdf

Well, when I ran the following command to read outputted serial data:
Code:
screen  /dev/tty.usbserial-A601EKZ6 250000

I get an endless supply of this:


Do I need to change something else before I can use this baud rate?

Thanks!
Aakash

PS. Here's the code I'm using. Basically, I need the higher baud rate so I can output data faster. I'm needing to transfer ~30bytes in about a millisecond and (10/57600)*30= ~5ms. So, 250000K might remedy this, as (10/250000)*30 = 1.2ms

Code:
int counter = 0;
unsigned long oldTime = 0;
String output = "";
void setup(){

  Serial.begin(250000);
  Serial.println("---BASIC SERIAL TIMER APP INITIALIZED---");
  oldTime = micros();
}
void loop(){
 
      output += micros()-oldTime;
      oldTime = micros();
      Serial.println(output);
      output = "";
      counter++;
     

}
9  Using Arduino / Networking, Protocols, and Devices / Re: Reliable UART between Arduino and Bluetooth Module for Large Data on: December 03, 2012, 06:00:31 pm
Just an update: I've tested a ~1000 byte TX/RX @ 9600 bps and it worked perfectly. So your comment was correct Paul5. Thank you smiley
10  Using Arduino / Networking, Protocols, and Devices / Re: Reliable UART between Arduino and Bluetooth Module for Large Data on: December 03, 2012, 11:07:12 am
Paul5,

Thanks for your response. The Arduino will not be doing anything when data is received. The logic (communicating with I2C devices, SPI devices, etc) will be done after a full packet is received, and based on the contents of the packet. The Bluetooth devices will not send any more packets until a response is received from the Arduino, which will be after all other logic has completed.

Essentially, the loop() function will be running unimpeded when data is being received. Incoming data will stored into the RAM immediately.

So, if I understood what you said correctly, I shouldn't worry about any buffer overruns or anything of the sort?

Thanks again,
Aakash
11  Using Arduino / Networking, Protocols, and Devices / Reliable UART between Arduino and Bluetooth Module for Large Data on: December 02, 2012, 10:37:32 pm
Hey all,

I'm working on a project that uses a Bluetooth module connected via UART to an Arduino Pro (m328p @ 8MHz/3.3V).

The devices that will be connecting to the Bluetooth module will be communicating via well formed packets (headers with packet size, check sum, etc). The devices will typically send packets in sizes from a couple of bytes all the way up to ~200 bytes. Even bigger in some cases. From my understanding, the UART buffer is only 64 bytes on the Arduino, and there is also no flow control.

The Arduino can send out large data packets fine (I've tested <100 byte sized strings). Though, incomming data packets is what I'm concerned about. Right now the module is running at 115200 bps, and I'm worried that some byte loss might occur between the Arduino and module. If I lower the bit rate to 9600 bps (the lowest I can select for the module I'm using), would this issue be averted?

An additional note: I'm planning on using the serialEvent() interrupt to drain the incomming byte buffer by storing the packet data bytes into a byte array in the RAM as soon as they're received. Then doing any logic afterwards.

Thanks all,
Aakash
12  Using Arduino / Microcontrollers / Re: Set Low Fuse Bit, Now Can't Program over ISP on: November 18, 2012, 11:43:20 pm
It's making more sense to me now:

- with 128kHz applied to XTAL2 you are getting 16KHz on CLKOUT
- so you need to program it with SCLK not exceeding 4KHz
- so -B 250 is barely enough cycle time, if avrdude does use the -B parameter to set the SCLK rate of the AVRISPmkII

So try with 128KHz applied to XTAL2 again, but this time:

- try avrdude with a -B parameter greater than 250
- try using AVR Studio, with the SCLK frequency in the user interface set to 4KHz or even lower.

If that fails, try with 32768Hz or so applied to XTAL1 or XTAL2 (whatever gives you a clean CLKOUT signal) and use SCLK <= 1kHz in AVR Studio. The docs say you can't program the flash below 2KHz, but you can do a chip erase.

Yep! That worked. I set the clock source (D9) from the Arduino  to 128KHz and connected it to XTAL2. After that, I went into AVR Studio and set the rate to 4.209KHz (or something very close) and the connection was very unstable. Though, I was able to set the fuses back to factory state after trying to write them a few times. Now it's working without the external clock source!

I'll try to write the low fuse to use the resonator tomorrow, or sometime soon, but correctly this time :-)

Thanks a lot dc42, and all!
13  Using Arduino / Microcontrollers / Re: Set Low Fuse Bit, Now Can't Program over ISP on: November 18, 2012, 04:19:16 pm
The reset pin is connected to a 10k resistor connected to VCC. Would this pose issues?

You would need to cut or remove that. As you can imagine.

Also, will I be able to use the existing ICSP header to reprogram it?

No. There are about 20 jumpers you have to run from the programmer to the chip. You would need access to most of the pins on the Atmega328.

Unfortunately for me, the latter won't be possible. I'll probably just send it out tomorrow and just get the resonator/avr replaced.

For future reference, what fuses should I be using in order to make the atmega328p use the 8MHz resonator?
14  Using Arduino / Microcontrollers / Re: Set Low Fuse Bit, Now Can't Program over ISP on: November 18, 2012, 03:59:46 pm
dc42:

I set REQUIRED_FREQUENCY  (128000) and connected the logic analyzer to CLKOUT.

When connecting the source to XTAL1 nothing happens to CLKOUT. But when connecting it to XTAL2 the attached screenshot is the output.

EDIT: When D9 is connected to XTAL2, I ran this command "avrdude -c avrispmkII -p m328p -P usb -B250" and also -B500 and it still failed to initialize.

Nick:

The reset pin is connected to VCC through a 10k resistor. Would this pose issues?

Also, will I be able to use the existing ICSP header to reprogram it?
15  Using Arduino / Microcontrollers / Re: Set Low Fuse Bit, Now Can't Program over ISP on: November 18, 2012, 03:12:59 pm
That should have been exactly the right thing to do. Try doing it again, but also reduce REQUIRED_FREQUENCY in case 1MHz is a little high, given that you have the resonator still connected and a 1.5K resistor in series with the clock signal. As the Arduino you are using to generate the clock is also 3.3V, I think you can also safely try it without the 1.5K series resistor. What you are looking for is a signal on CLKOUT at a reasonable frequency.

So what you're saying is that I should lower the REQUIRED_FREQUENCY to a number until CLKOUT starts showing a steady clock? Right now, at 1MHz, the analyzer doesn't detect anything on CLKOUT at that speed.
Pages: [1] 2 3