Moving data between arduinos

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Moving data between arduinos

Post by adafruit_support_rick »

I didn't look at your wifi stuff at all - I don't have a wifi shield, so I just disabled and ignored it.

Looking at it now, I see that you never actually try to connect to wifi in loop(). You simply check to see if it's connected.

You certainly don't want those calls to onRequest and onReceive in loop(). I don't know what the delay(500) is for, either.

Additionally, you close the data file when you're done with the wifi transfer, but you never open a new file. You need to do that, so that you can continue to save GPS data.

I don't know anything about the wifi shield, so I can't really help you with that stuff. But the entire GPS side and the I2C section of the wifi side are both solid. If you stay away from changing any of that while you're working out the wifi stuff, you should be golden.

The way I would go forward would be to write a temporary sketch that just monitors wifi and uploads data files. Once that was working, then I'd merge the relevant parts of it into the main wifi sketch.

xEDWARDSx
 
Posts: 94
Joined: Tue Jun 04, 2013 2:27 pm

Re: Moving data between arduinos

Post by xEDWARDSx »

Ok then the question i have is if I place the receive and request lines in the setup, does that sketch ever make it out of those two routines? If it does how will those routines be used again, if the arduino is never restarted?

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Moving data between arduinos

Post by adafruit_support_rick »

receiveEvent() and requestEvent() are instances of what is known as a "callback routine". The Wire library will call those functions directly whenever there is something for them to do.

Wire.onRequest() and Wire.onReceive() just tell the Wire library which functions to call. It's like saying, "Hey, Wire library - whenever you get some data from somebody, call this here function", and, "Whenever somebody asks for data, call this here other function"

That's why you only need to do that once, in setup. It's also why you never have to call onReceive and onRequest directly - the Wire library does that automatically.

xEDWARDSx
 
Posts: 94
Joined: Tue Jun 04, 2013 2:27 pm

Re: Moving data between arduinos

Post by xEDWARDSx »

That makes perfect sense.So the problem i'm having was that the code was getting to the wifi connection, but the gps data was still coming through. Which was in tern makeing everything super slow and messing with the wifi shield sending the data to the server. I see that you set up a bool wifiConnect, so i used that to make a new request that sends a 'S' when it is connected. That will make the gps not send the data over the wire and just discard those logs. Is that something i should do?

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Moving data between arduinos

Post by adafruit_support_rick »

Oh, OK - Actually, my intention - and I see that I forgot to actually do this - was to use the wifiConnected bool in receiveEvent, like so:

Code: Select all

  if (!wifiConnected)
  {
    dataFile.write(buffer, howMany);       // Write the buffer to the SD 
    // Serial.write(buffer, howMany);         // print the buffer
  }
But if the actual wire transfer is interfering with the wifi, then yeah - you want to stop the GPS transfers.

First, however - if you don't have the Serial.write commented out (as above), give that a try. That may be what is discombobulating the Wifi.

You don't need the 'S' thing at all. Just don't send the 'A' while wifi is connected. You don't need to do anything to the GPS side - if it doesn't see an 'A' within 500ms, it will simply bail out and wait for the next sentence, which is what you want it to do.

You can handle the whole problem by simply adding the test for wifiConnected to requestEvent:

Code: Select all

void requestEvent()
{
  if (receivingSentence) 
  {
    Wire.write('D');
    Serial.println("ack D");
  }
  else 
  {
    if (!wifiConnected)    //only send the 'A' if wifi is NOT connected.
    {
      Wire.write('A');
      Serial.println("ack A");
    }
}

xEDWARDSx
 
Posts: 94
Joined: Tue Jun 04, 2013 2:27 pm

Re: Moving data between arduinos

Post by xEDWARDSx »

I tried that and it doesn't stop the transfer when it connects to the wifi it only stops when a client connects to the server (if it ever makes it that far).

xEDWARDSx
 
Posts: 94
Joined: Tue Jun 04, 2013 2:27 pm

Re: Moving data between arduinos

Post by xEDWARDSx »

I extended the time that it searches for a client and it works better now, but i''m having problems with the SD card. When i try to take it out and read the file its some crazy symbols and stuff. When it connects to the server and displays the file the strings are fine. Also i'm not sure it it is possible but is there a way to power one arduino with the usb then from that one power another arduino, or do i need two separate power supplies?

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Moving data between arduinos

Post by adafruit_support_rick »

xEDWARDSx wrote:I tried that and it doesn't stop the transfer when it connects to the wifi it only stops when a client connects to the server (if it ever makes it that far).
Well, the code sets wifiConnected to true when (status == WL_CONNECTED). So maybe there's some other status value you should be checking for.

Code: Select all

    if (status == WL_CONNECTED)
    {
      server.begin();
      while (receivingSentence);  //wait for current sentence to finish
      wifiConnected = true;
      dataFile.close();

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Moving data between arduinos

Post by adafruit_support_rick »

xEDWARDSx wrote:but i''m having problems with the SD card. When i try to take it out and read the file its some crazy symbols and stuff. When it connects to the server and displays the file the strings are fine.
Well, it's all the same data, so it must be right. What are you using to read the file? It's just a plain old text file. It was perfectly readable here when I did it. Can you post a sample of the gibberish?
xEDWARDSx wrote:Also i'm not sure it it is possible but is there a way to power one arduino with the usb then from that one power another arduino, or do i need two separate power supplies?
Assuming there's enough current, you can jumper 5V and GND between the two arduinos.

xEDWARDSx
 
Posts: 94
Joined: Tue Jun 04, 2013 2:27 pm

Re: Moving data between arduinos

Post by xEDWARDSx »

I'm trying to comment all of the code just need a little help with the stuff you put in.

Code: Select all

int stringsize = strlen(currentSentence) + 1;
      int currentOffset = 0;
      uint8_t howMany;
      while (stringsize > 0)
      {
        howMany = min(32, stringsize);

        Wire.beginTransmission(4);
        Wire.write((uint8_t*)&currentSentence[currentOffset], min(32, howMany));


In this part you look for the size of the GPS string then ad one bit to it, what does the current offset do? whle the string is greater than zero howmany is set to the string size or 32 bits then the readable data is sent over the wire. Is that correct?

Code: Select all

bool getAck(char ackChar, int timeout)
{
  unsigned long pollTime = millis();  
  char receivedChar;
  bool gotAck = false;

  do {
    receivedChar = 0;
    Wire.requestFrom(4,1);
    Serial.println("Waiting for ack");
    while ((Wire.available() == 0) && (millis() < (pollTime + timeout)));
    if (Wire.available() != 0) {
      receivedChar = Wire.read();
    }
  }  
  while ((receivedChar != 0) && (receivedChar != ackChar));

  gotAck = (receivedChar == ackChar);

  Serial.print(gotAck?F("received ack "):F("did not receive ack ")); 
  Serial.print(ackChar);
  return gotAck;
}
The pollTime is the time that is counted down from the start of the code. in the do loop it requests a bit. while the wire is available = 0 and "(millis() < (pollTime + timeout)))" (not sure what that is for). recieve the char, loop through if the char is not 'A' or 'D'. If the char is 'A' or 'D' then print it on the serial monitor. Is that correct?

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Moving data between arduinos

Post by adafruit_support_rick »

xEDWARDSx wrote:In this part you look for the size of the GPS string then ad one bit to it, what does the current offset do? whle the string is greater than zero howmany is set to the string size or 32 bits then the readable data is sent over the wire. Is that correct?
C strings always end with a byte of 0. strlen gives you the length of the string, not including that terminal null character. So I add 1 because I want to make sure I send the null.
Meanwhile, a string is just a character array. currentSentence is a pointer to the first character in the array. currentOffset is an array index to is the beginning of the current 32-character substring we're going to send.
stringSize is the amount to data remaining to send, howMany is the length of the current substring to send.
xEDWARDSx wrote:The pollTime is the time that is counted down from the start of the code. in the do loop it requests a bit. while the wire is available = 0 and "(millis() < (pollTime + timeout)))" (not sure what that is for). recieve the char, loop through if the char is not 'A' or 'D'. If the char is 'A' or 'D' then print it on the serial monitor. Is that correct?
pollTime is the time at which we sent the Wire.requestFrom(4,1). timeout is how long we want to wait for a response. Let's say we send the requestFrom at pollTime 10000ms, and our timeout value is 500ms. We will wait for a response until millis() tells us that the current time is 10500ms or later. That is, millis() is less than (pollTime + timeout).
When we call getAck, we also tell it which ack character we're looking for (doesn't have to be 'A' or 'D' - could be anything). If we timeout without receiving a character, then receivedChar will be 0, and the loop will exit. If we received a character, but it's not the one we want, then we'll loop around and try again. If we received the character we want, then we'll exit the loop.
The function returns the boolean value gotAck, which is set like this:

Code: Select all

  gotAck = (receivedChar == ackChar);
(receivedChar == ackChar) is an expression which evaluates to a boolean value. We assign that to gotAck. This, if we got the character we're looking for, the function will return true. Otherwise it will return false.
This:

Code: Select all

gotAck?F("received ack "):F("did not receive ack "));
is something that many people absolutely hate about C. The form is <conditional expression>?<result if true>:<result if false>. So, the <conditional expression> is gotAck. If it evaluates to true, then the entire expression evaluates to "received ack ". If gotAck evaluates to false, then the entire expression evaluates to "did not receive ack ".
I mostly agree with the people who hate the form, but I find it very useful for debug messages. I seldom use it anywhere else. The alternative is:

Code: Select all

 . . .
  if (gotAck)
  {
    Serial.print(F("received ack "));
  }
  else
  {
    Serial.print(F("did not receive ack "));
  }
  Serial.print(ackChar);
  return gotAck;
}

xEDWARDSx
 
Posts: 94
Joined: Tue Jun 04, 2013 2:27 pm

Re: Moving data between arduinos

Post by xEDWARDSx »

Thank you Rick and Bill for all the help i'll chalk it up as done for now until i was to add to it. I'll defiantly be ordering more from adafruit in the future.

Locked
Please be positive and constructive with your questions and comments.

Return to “General Project help”