Show Posts
Pages: 1 [2] 3
16  Forum 2005-2010 (read only) / Development / Re: using both serial and newsoftserial on: July 04, 2009, 03:08:56 pm
Hi Brutus,
Are you certain about the buffer with "newsoftserial"? I thought that was one of the advantages...that and interrupts. But regardless, 90% of my issues are with the UART ports & lost bytes. Seems that as the arduino is reading the soft-serial port I lose incoming data, and rarely the reverse.

The mega is nice, but not really an option here. Thanks, tho, for your pointers.

David
17  Forum 2005-2010 (read only) / Development / using both serial and newsoftserial on: July 04, 2009, 11:49:02 am
Hi all,
So I have a feeling I'm asking way too much of my little Arduino chip, but a man can dream, can't he?

I've been doing some testing for a much larger set-up. Right now I have an xbee and two arduino pro minis in series:  i.e. xbee Tx to Arduino #1 UART Rx, Arduino #1 UART Tx to Arduino #2 UART Rx, Arduino #2 UART Tx to xbee Rx. On #2 I also have a digital compass attached to pins 2 and 3 and am using the "newsoftserial" library to read the data. Arduino #1 initiates the process by reading all the analog pins and writing the packet to its UART Tx, this is read by Arduino #2, and after receiving the line feed byte, reads its own analog pins, adds its data to the Arduino #1 data, adds the extra bytes to make an xbee API packet and sends it off to the xbee via it's UART Tx pin. As soon as it is done, it takes the last complete packet it has received from the compass, adds the extra xbee API bytes, and sends this as well. Right now I have the serial UART @ 115k baud, newsoftserial @ 19.2k. Both the compass and the analog pins are sampled @ 20Hz.

Here's my problem. Currently about 25% of my packets are missing bytes, with the missing bytes always being the data received from the UART Rx pin from the first Arduino. Of the 7 bytes that are coming in (6 data, 1 line feed), I always get the first two bytes and the line feed (since that triggers everything...I could very well be losing the line feed, too, I just haven't set up a way to test that yet). If it's 3 bytes of data, it's always the first 2 and the 4th. If 4, it's the first 2, the 4th and the 6th. As soon as I turn the compass off, I have no problems, no lost bytes presumably since there is nothing to read anymore. This is making me think the UART read and newsoftserial read are interfering. The data from the compass is consistently good, but maybe once every minute the line feed from the compass is missed and I get 2 readings in one packet.

So the question(s) (finally): is it even possible to expect the chip to be able to read a near continuous stream of data from 2 serial ports and not drop bytes? How large of a buffer do the UART serial ports and newsoftserial ports have? I've tried adding delays here and there with no improvement (although maybe I should switch those to time-based triggers instead now that I think about it). I've tried different combinations of "if (Serial.available() > 0)" vs. "while (Serial.available() > 0)" for both types of serial reads with no improvement, either. This is all so I can avoid adding another 70mA to a battery powered system (in the form of an extra xbee and mini to handle the compass data separately)...so I might just have to suck it up especially since the entire system is actually 13 arduino minis! And I'd really like to not go any lower than 20Hz if I can avoid it (yes, I am asking the impossible...I know)...

Anyway...if anyone has any pointers in my quest I would be eternally grateful!

Thank you!
David
18  Forum 2005-2010 (read only) / Interfacing / Re: vectornav, mega, and SPI on: August 10, 2010, 12:10:46 pm
wait...just looked at the schematic and sparkfun's level shifter uses the BSS138 mosfet. Even better!
David
19  Forum 2005-2010 (read only) / Interfacing / Re: vectornav, mega, and SPI on: August 10, 2010, 11:06:20 am
@Hallicarnassus:
I have, but that's not really the problem. The problem is the mis-match in voltages on the communication lines. The arduino is still sending out voltages up to 5V, while the vectornav expects things around 3V.

@mrmeval:
I saw your post last night just about the time I found the level shifter on sparkfun (my home away from from):
http://www.sparkfun.com/commerce/product_info.php?products_id=8745

I'm going to grab a bunch anyway since I'm using a bunch of wireless radios @3.3V connected to arduinos @5V via the UART pins (always seem to forget that I need to convert the levels).

The biggest note I saw wrt the shifter above was that it might not be quick enough for the higher frequency shifting of the SPI pins (which I think is what CharlieD is referring to above). This article was very helpful:
http://delphys.net/d.holmes/hardware/levelshift.html
in particular using the "Fairchild Semiconductor BSS138 N-channel enhancement mode MOSFET". I have orders ready to go at both sparkfun and digikey, so we'll see if this helps.

Also, I know it's been cited a couple times in the forum, but just in case sparkfun has a helpful tutorial on level shifting:
http://www.sparkfun.com/commerce/tutorial_info.php?tutorials_id=65

Thanks,
David

20  Forum 2005-2010 (read only) / Interfacing / Re: vectornav, mega, and SPI on: August 09, 2010, 04:18:40 pm
So I talked to vectornav developers and they believe it might be a voltage level mis-match. Although the vectornav is powered off a 5V supply, the SPI interface uses 3V. Anybody know what the voltage levels are coming out the SPI pins on the mega running at 5V?

Thanks,
David
21  Forum 2005-2010 (read only) / Interfacing / vectornav, mega, and SPI on: August 06, 2010, 03:55:28 pm
Hi all,
I need some guidance here. I'm new to SPI and am not having much luck getting the data I want. The set-up is a vectornav sensor connected to the 4 SPI pins on the arduino mega. And here's my not-so-polished code:

Code:
/*
code to read vectornav data via an arduino mega SPI pins

SPI mode uses a lightweight binary message format over the SPI data bus. The start of a command is signaled
by pulling the VN-100 module's chip select pin (pin 23) low. Both the chip select line and clock are active low.
The first byte transmitted to the module should be the command ID and then a variable number of bytes will
follow dependent on the type of command specified. A communication transaction can be cancelled at any time
by releasing the chip select pin. Pulling the pin low again will start a new communication transaction. All binary
data is sent to and from the chip with most significant bit (MSB) first in little-endian byte order with all
numbers either represented as 32-bit floating point or 32-bit unsigned integers. For example the serial baud
rate register with a value of 9600 (0x2580) would be sent across the SPI as a 0x80, 0x25, 0x00, 0x00. Data is
requested from and written to the device using multiple SPI transactions.
 */

#define DATAOUT 51      //MOSI
#define DATAIN  50      //MISO
#define SPICLOCK  52    //sck
#define SLAVESELECT 53  //ss

byte serialIn; // container to hold incoming serial data

byte clr;

byte attitude[16]; // yaw, pitch, & roll

unsigned long start_sample;
unsigned long end_sample;
unsigned long elapsed_time;


void setup()
{
  Serial.begin(115200); // main UART pins
  delay(500);
  
  for (int i = 0; i < 16; i++) {
    attitude[i] = i;
  }

  // SPI configs
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device

  // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/4 rate (fastest)

  SPCR = B01010000; //MPIE=0, SPE=1 (on), DORD=0 (MSB first), MSTR=1 (master), CPOL=0 (clock idle when low), CPHA=0 (samples MOSI on rising edge), SPR1=0 & SPR0=0 (4MHzHz)
  clr = SPSR;
  clr = SPDR;
  delay(500); // everyone else is doing it; i am a lemming

} // end setup

void loop() {
  // check UART pin for any incoming data
  if (Serial.available() > 0) { // mail call
    serialIn = Serial.read();

    // let's take a some sample
    if (serialIn == 33) { // = ! = time to start sampling
      // 01 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00

      digitalWrite(SLAVESELECT,LOW);
      
      attitude[0] = spi_transfer(0x01);
      delayMicroseconds(100);
      attitude[1] = spi_transfer(0x08);
      delayMicroseconds(100);
      attitude[2] = spi_transfer(0x00);
      delayMicroseconds(100);
      attitude[3] = spi_transfer(0x00);
      delayMicroseconds(100);
      attitude[4] = spi_transfer(0x00);
      delayMicroseconds(100);
      attitude[5] = spi_transfer(0x00);
      delayMicroseconds(100);
      attitude[6] = spi_transfer(0x00);
      delayMicroseconds(100);
      attitude[7] = spi_transfer(0x00);
      delayMicroseconds(100);
      attitude[8] = spi_transfer(0x00);
      delayMicroseconds(100);
      attitude[9] = spi_transfer(0x00);
      delayMicroseconds(100);
      attitude[10] = spi_transfer(0x00);
      delayMicroseconds(100);
      attitude[11] = spi_transfer(0x00);
      delayMicroseconds(100);
      attitude[12] = spi_transfer(0x00);
      delayMicroseconds(100);
      attitude[13] = spi_transfer(0x00);
      delayMicroseconds(100);
      attitude[14] = spi_transfer(0x00);
      delayMicroseconds(100);
      attitude[15] = spi_transfer(0x00);
      delayMicroseconds(100);

      digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer

      for (int i = 0; i < 16; i++) {
        Serial.print(attitude[i], BYTE);
      }
      Serial.print(10, BYTE);
      
    } // end sample if/then

  } // end UART while loop

}


byte spi_transfer(volatile byte data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

So with the above code I'm just trying to get attitude vales (heading, pitch, roll). The message I'm sending (in hex) is:

01 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00

what I should get back should be something like:
00 01 08 00 39 8A 02 43 FD 43 97 C1 CD 9D 67 42

(the last 12 bytes = -130.54, -18.91, +57.90)

What I'm getting is:
1 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0
or
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

I feel like I'm close since it's at least writing over my init values for the array, but after a couple days of reading up on SPI I'm a bit at a loss at what to try next, or if there is an error in my code or ??

Any advice? Also FYI I can communicate just fine via the UART pins (one of the reasons why getting the mega), but was looking for a faster method for getting data out of the sensor.

TIA,
David

22  Forum 2005-2010 (read only) / Interfacing / Re: mixing 3.3V and 5V in a very tiny space on: July 04, 2009, 03:34:27 pm
Hi all,
To sort of conclude the conversation here, I received a handful of the sparkfun devices:
http://www.sparkfun.com/commerce/product_info.php?products_id=9132

...and am a very happy camper. Now everything can exist in 5V land...and there was much rejoicing.

Best,
David
23  Forum 2005-2010 (read only) / Interfacing / Re: mixing 3.3V and 5V in a very tiny space on: June 29, 2009, 12:35:44 am
Hi all,
Thank you all so much for the replies! What it's highlighted is a deficiency in my electronics knowledge, however (and I must say I've had quite a whirlwind education over the past couple months!)! If I understand correctly now, simply having a 3.3V power source for the xbee and a 5V supply for the others will not do...I must also convert the serial (TTL) messages between the two!

The adafruit version seems ideal, but it's a bit too large some of my applications. Sparkfun also has one:
http://www.sparkfun.com/commerce/product_info.php?products_id=9132
however there seems to be quite a few answered questions wrt level shifting (whether it does it) and 150mA vs 250mA current threshold. Actually the other sparkfun BOB mentioned above seems lovely, if only it didn't need both power sources (the size is certainly right). @EmilyJane: slick is ideal! But the concern is also what the max the xbee can receive as logic 1 without creating smoke, which is what I am trying to figure out now.  Actually does anybody know what the minimum voltage the pro mini can accept as logic 1 input (r the max the xbee series 1 can handle)?

Anyway, thank you all for the advice. So much more to learn! And here I thought 12 years of college was enough smiley

Cheers,
David
24  Forum 2005-2010 (read only) / Interfacing / mixing 3.3V and 5V in a very tiny space on: June 28, 2009, 02:38:11 pm
Seems to be my week for asking questions about power!
After reading this thread about running the 5V/16Mhz Pro Mini @ 3.3V:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1236970695
I've tried it myself and it seems to be working OK...but as those in the thread who have tried to essentially "overclock" their 16Mhz mini (this is the 328 chip, FYI)...all is good at room temperature. Well, we've had some hot days here in the valleys of Los Angeles and my data isn't looking so good. Could be other issues, but I'm thinking it's time to revisit the overclocking issue. The only reason I need to have 3.3V is to power an xbee in the same system. There is also a compass in the system that can tolerate 3-6V.

So my two questions:
1. would there be an issue powering the minis and compass with 5V and the xbee with 3.3V in the same system (and assuming a common/shared ground)?

2. is there a simple, uber-compact method for converting 5V to 3.3V, or a way to have the mini provide 3.3V given a 5V source?

I know the easy answer would be to use a 3.3V/8Mhz Pro Mini, but I'm sitting on 20 of the 16Mhz for this project (in order to work with an earlier version of newsoftserial), and would rather not purchase any more for while!

Thanks for any advice!
Best,
David
25  Forum 2005-2010 (read only) / Interfacing / powering with an ipod battery on: June 27, 2009, 11:38:10 am
Hi all,
I've been searching for battery options for a project I've been working on. Ideally I'm looking for a small form factor, lots of capacity, and ability to support ~100-120mA, powering an xbee, arduino pro mini, and a digital compass. Sounds easy enough, eh?   OK, so not *that* easy. My current (no pun intended) solution is to use a couple of rechargeable coin cells, but in my searching I came across replacement batteries for ipods at a local electronics store (e.g. lenmar model# PMPAIPMINI). 3.7V, 720mAh, super flat and relatively small...but can't find any info on max current supported. Same with similar batteries from others like duracell. I sent an inquiry to Lenmar but haven't heard back, so was curious if anyone else had tried to used these batteries in their work? I would imagine the iPod mini could draw about as much current (playing music, leaving screen on, etc.). I'm also a bit worried about charging it. I have a couple of the sparkfun LiPoly chargers (charges both Li-ion and LiPoly batteries) which I am hoping will work. The battery seems ideal for what I need...but just have this silly desire not to burn down my house! Any advice would be greatly appreciated!

Cheers,
David
26  Forum 2005-2010 (read only) / Interfacing / Re: xbee (series 1) dropping characters on: June 09, 2009, 12:49:06 am
Just to keep everyone in the loop since I know there is SO much interest in my woes smiley

Turns out that the firmware was a bit out of date (the firmware list I found on digi's website apparently needs some updating, too). Since updating (version 10CD for those keeping score), I've gone from a bad packet every second to none. So that's quite nice. Other notes from digi's support included setting the packetization timeout (RO) to 0x03. Probably decreasing the baud to 57.6k will ensure that I always get good packets.

One question, tho. Seems like it would be smart to implement some hardware flow control between the xbee and my arduino pro mini. I basically need the xbee to tell the mini to stop sending it data for a moment. This can be done on the xbee via the CTS pin (pin 12). From what I can tell, when the buffer is close to full the xbee sets the pin high. When things are OK, it sets the pin low. What I don't know is what to do on the mini side. Any advice? Can the CTS pin on the xbee be connected directly to one of the end pins on the mini? Or is this something I need to monitor in software on the mini? I'm a bit lost here.

Thanks in advance for any pointers.

Cheers,
David

27  Forum 2005-2010 (read only) / Interfacing / xbee (series 1) dropping characters on: June 08, 2009, 01:04:54 am
Hi all,
I was wondering if anyone had any issues with dropped characters when sending data from an arduino to a CPU via xbee? I'm right now doing some tests between xbee and bluetooth, and while I'm lovin' many of the aspects of the xbee, not so keen on the lost data. Sometimes it's a space, sometimes a line feed, sometimes a digit will be missing. Whatever it is, it ain't predicable, and it sure ain't makin' me happy. If I use the exact same sketch and app on my mac with my bluetooth modem (bluesmirf), nothing is dropped.

I'm using 2 xbee radios (series 1, 802.15.4), one set as the coordinator (and attached to my CPU), one as an end device (attached to an arduino). Firmware 1084. Both set up in transparent mode, sleep = 0, packetization timeout = 0. Everything set to 115k baud, but switching everything to 57.6k didn't show any improvement. Slowing the sample rate down to 10 Hz didn't help either (not much point in going lower for what I'll need this to do).

Anybody else experience something like this? It's really not usable like this if I can't trust the data coming in, which makes me think I have something setup incorrectly!

Thanks for any pointers. And please let me know if it would be helpful to show a sketch.

Best,
David

28  Forum 2005-2010 (read only) / Interfacing / Re: Connecting a whole bunch of Arduinos on: June 07, 2009, 01:13:49 pm
Hi Ran,
Thank you so much for your help with this (and apologies for the delay in responding...been spending time switching my wireless from bluetooth to xbee, and am now back on this problem).

For some reason I haven't been able to get the compass and an arduino to play nicely at 115k, so I've been stuck at 57.6k (compass is fine @ 115k, mini is fine @ 115k, but not so when daisy-chained together as described in the first post...I get lots of bad characters, almost like a baud rate mismatch...but not). Since clearly I'm sending a ridiculous amount of data, I might as well move the compass to it's own dedicated radio, then try to split the arduinos into 2 chains and incorporate your suggestions above.

I'll be sure to report back once I've figured this out.

Much thanks,
David

29  Forum 2005-2010 (read only) / Interfacing / Connecting a whole bunch of Arduinos on: May 30, 2009, 07:38:16 pm
Hi all,
I'm looking to get some advice on speeding up a little serial chain of arduino pro minis.
I have 13 pro minis plus 1 digital compass (ocean server) communicating to my mac via a bluetooth (bluesmirf). Everything is daisy chained together: Tx of modem >> Rx of compass >> Tx of compass >> Rx of Arduino #1 >> Tx or Arduino #1 >> ... >> Tx or Arduino #13 >> Rx of modem. It's quite an impressive collection of tiny flashing LEDs. The compass is at the beginning of the chain since it sends data as soon as it gets powered up (can't poll it), but I can at least set it's sampling rate. The compass is serial output and is read by the first arduino via the Rx pin, where the line feed character (the end of the packet from the compass) triggers a print of the data from all the analog pins (basically adding the data to the end of the packet), and passes it down the line. I think I've set it up so that while the minis are not dealing with data from the serial port they are reading data from the analog pins. This was one of my efforts to speed things up a bit, thinking that if it wasn't reading AND printing the data when it received a line feed it might take less time. I was originally planning on setting up a little I2C network until I read the fine print about it needing 2 of my 6 analog ports...hence the daisy chain.

Everything is working great, however with each arduino that I've added I've had to lower the sampling rate to ensure that the entire packet (all the data from the compass and the 13 minis) reaches the computer. It now sits at about 12Hz, and was hoping for closer to 40Hz. My code is below, and was wondering if anyone had any pointers on how to speed this up.

Thank you in advance for any guidance.

Cheers,
David

Code:
int statusLED = 13; // status LED on Arduino
byte serialIn; // container to hold incoming serial data
// values below are used to determine sampling inverval
unsigned long time_now = 0; // current time
unsigned long time_lastprint = 0; // previous time
unsigned long dt = 0; // elapsed time
unsigned long sampleclock_now = 0; // current time
unsigned long sampleclock_lastread = 0; // previous time
unsigned long sampleclock_dt = 0; // elapsed time
int photo[6]; // holds all the data for the photosensors
unsigned long readclock_0 = 0;
unsigned long readclock_1 = 0;
unsigned long readclock_dt = 0;

// ********** change this for each Arduino in the chain **********  //
int place_in_chain = 1; // = 1 is master, others = slave
// ***************************************************************  //

void setup()
{
  Serial.begin(57600); // 57600 115200

    pinMode(statusLED, OUTPUT); // declare pin as output

  for (int i=0; i < place_in_chain; i++){ // flash status LED # flashes = assignment in chain
    digitalWrite(statusLED, HIGH);
    delay(150);
    digitalWrite(statusLED, LOW);
    delay(150);
  } // end LED flash for loop

  for (int i=0; i <= 6; i++){ // set sensor data to 0
    photo[i] = 0;
  } // end for

} // end setup

void loop()
{
  // reads data from analog inputs in background so when line feed comes in
  // it merely prints the current values rather than taking time to read the ports
  // hopefully this will speed up the sampling a bit given the number of Arduinos in our chain
  readclock_0 = micros();
  readclock_dt = readclock_0 - readclock_1;
  if (readclock_dt >= 1000) // = 1 ms
    getInputData(); // get data from analog inputs
  readclock_1 = readclock_0;

  if (place_in_chain == 1) { // I am the master
    while (Serial.available() > 0) { // check serial buffer for any data
      serialIn = Serial.read(); // assigns incoming byte to serialIn array
      if (serialIn == 10) { // line feed = end of packet from compass
        Serial.print(" "); // add a space before getting pin data
        getElapsedTime(); // get elapsed time since last pass and print it
        printInputData(); // add data from analog inputs
        Serial.println(); // print a line break  
      } // end if for line feed character

      else if (serialIn == 44) { // 44 = comma
        Serial.print(" "); // replace comma with a space
      }
      else {
        Serial.print(serialIn, BYTE); // if not a line break, then pass along Rx (compass) to the Tx pin (to the modem)
      }
    } // end while
  }
  else {
    while (Serial.available() > 0) { // check serial buffer for any data
      serialIn = Serial.read(); // assigns incoming byte to serialIn array
      if (serialIn == 10) { // line feed = end of packet from previous arduino
        Serial.print(" "); // add a space before getting pin data
        printInputData(); // add this arduinos data to packet
        Serial.println(); // print a line break
      }
      else { // it's not a line feed, so pass the data along
        Serial.print(serialIn, BYTE);
      } // end serialIn if

    } //end while loop

  }
}


void getInputData() {

  photo[0] = analogRead(0);
  photo[1] = analogRead(1);
  photo[2] = analogRead(2);
  photo[3] = analogRead(3);
  photo[4] = analogRead(4);
  photo[5] = analogRead(5);

} // end getInputData

void printInputData() {

  // add a header
  Serial.print("photo_");
  Serial.print(place_in_chain);
  Serial.print(" ");

  Serial.print(photo[0]);
  Serial.print(" ");
  Serial.print(photo[1]);
  Serial.print(" ");
  Serial.print(photo[2]);
  Serial.print(" ");
  Serial.print(photo[3]);
  Serial.print(" ");
  Serial.print(photo[4]);
  Serial.print(" ");
  Serial.print(photo[5]);
  Serial.print(" ");

} // end printInputData

void getElapsedTime() {
  time_now = millis();
  dt = time_now - time_lastprint;
  Serial.print(dt); // should be last element in list
  Serial.print(" ");
  time_lastprint = time_now;
} // end getElapsedTime


30  Forum 2005-2010 (read only) / Interfacing / Re: power needs for 13 arduino pro mini's + on: May 07, 2009, 08:37:08 am
I meant too much more power than I measured with the ATmega128 smiley

Thanks.
Pages: 1 [2] 3