Go Down

Topic: Connecting Uno R3, CC3000 and PN532 - Problem with memory --- [SOLVED] (Read 5156 times) previous topic - next topic

greensquirrel

Sep 09, 2014, 12:10 pm Last Edit: Sep 12, 2014, 12:54 pm by greensquirrel Reason: 1
Hello Guys,

this is my first time posting in the forum since I'm new to Arduino, so please be kind  ;).
Me and a colleague of mine have been given a Project to create with arduino hardware.

The Project is, that you should be able to read NFC tags with the arduino
and send them to a server to be checked and eventually being written into a db.

The hardware:
Arduino Uno R3 (http://funduino.de/index.php/shop/product/view/2/4)
Adafruit CC3000 (http://www.adafruit.com/products/1469)
Adafruit PN532 (http://www.adafruit.com/products/789)
Stepper Motor (not yet included and not relevant for the problem)

Now on to the Problem:
When we're using the shields separately (meaning connecting the arduino to either of the shields by itself), the shields work fine. The cc3000 gets a connection and the PN532 reads cards.
Now we've tried to stack them together for live use. That's where the trouble starts...

If I connect the PN532 5V to the arduino 3.3V
and CC3000 VIN to 5V arduino,
the shields both do what they should with separate example sketches ('readMifare' and 'buildTest').

If I put my sketch in (which combines both of those sketches and some other stuff)
and comment out the initialization of either the PN532 or the CC3000, the other shield works.

Now if I try to use both, the CC3000 and the PN532,
the CC3000 tries to initialize, but falls into a loop of restarts.
I've read that that (possibly) is because of the lack of power supply.
(I've connected a 12V wall-wart by the way and it didn't work with that either)

The manual says, that the CC3000 needs 5V, but can work on 3.3V too (though I didn't find a source to explain how)
and the PN532 needs 3.3V to run.

Am I doing something wrong, or is it a problem with the arduino?
If I'm doing it wrong, how am I connecting these parts correctly?

I really am not that good with electronics and didn't find a sollution to my problem nearly a days worth of searching the net.
For your understanding I'll post the script I'm using and some pictures of the board setup.
Thanks in advance for ANY help you guys can give me (even if it's just  good guide for problems like mine) ^^

Regards,
Patrick

The part of the sketch that initializes the components (and also where the CC3000 gets stuck...)
Code: [Select]
//WLAN-Libraries
   #include <Adafruit_CC3000.h>
   #include <ccspi.h>
   #include <SPI.h>
   #include <string.h>
   #include "utility/debug.h"
   
   //NFC-Libraries
   #include <Wire.h>
   #include <Adafruit_NFCShield_I2C.h>
   
   //Motor-Libraries
   #include <Stepper.h>
   
   //NFC-shield PINs
   #define IRQ   (2)
   #define RESET (4)  // Not connected by default on the NFC Shield
   
   Adafruit_NFCShield_I2C nfc(IRQ, RESET);
   
 //Motor-settings
   
   const int stepsPerRevolution = 180;  // change this to fit the number of steps per revolution
                                        // for your motor
   
   Stepper Motor(stepsPerRevolution, 6,7,8,9);  // initialize the stepper library on pins 8 through 11:          
   
 //Wifi-settings
 
   // These are the interrupt and control pins
   #define ADAFRUIT_CC3000_IRQ   3  // MUST be an interrupt pin!
   // These can be any two pins
   #define ADAFRUIT_CC3000_VBAT  5
   #define ADAFRUIT_CC3000_CS    10
   // Use hardware SPI for the remaining pins
   // On an UNO, SCK = 13, MISO = 12, and MOSI = 11
   Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                            SPI_CLOCK_DIV2); // you can change this clock speed
   
   #define WLAN_SSID       "mySSID"           // changed for your convenience
   #define WLAN_PASS       "myPassphrase"
   // Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
   #define WLAN_SECURITY   WLAN_SEC_WPA2
   
   Adafruit_CC3000_Client www;  //defines how we will refer to the cc3000 connection object
   
   // What page to grab!
   #define WEBSITE      "10.2.10.170"  //NOTE: CC3000 doesn't seem to like the default localhost address of 127.0.0.1 - need to enter actual IP
   #define WEBPAGE     "/index.php"
   
   
   //this is the counter that will be used for uploading data
   long pollCounter = 1;
   
   //used for storing data for upload
   //set it to the data type that suits your data
   int
     NFC_ID, Session_ID, UID_final;
   
   //used for commands received from base station
   int
     command_open, command_close;
     
     boolean pollFlag = false;         //tells the sketch whether to poll or not
   
   //declare a variable to hold a numeric IP address
   //can be overridden below if you use lookup
     uint32_t ip = (192L << 24) | (168L<<16) | (1<<8) | 13;
   
   
   /**************************************************************************/
   /*!
       @brief  Initialization of the modules (Motor, Wifi, NFC-Reader)
   */
   /**************************************************************************/
   
   
   void setup(void)
   {
 //Set up the Motor for the lock
   
     // set the Motor speed at 60 rpm:
     Motor.setSpeed(60);
     
 //Set up the Wifi module
   
     Serial.begin(115200);
     Serial.println(F("Hello, CC3000!\n"));
   
     Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);
     
     /* Initialize the Wifi module */
     Serial.println(F("\nInitializing..."));                 //<======== Here the CC3000 gets stuck in a loop
     if (!cc3000.begin())                                          //                          when both shields are connected
       {
         Serial.println(F("Couldn't begin()! Check your wiring?"));
         while(1);
       }
     
     cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
     
     Serial.println(F("Connected!"));
   
     /* Wait for DHCP to complete */
     Serial.println(F("Request DHCP"));
     while (!cc3000.checkDHCP())
       {
         delay(100); // ToDo: Insert a DHCP timeout!
       }  
   
     /* Display the IP address DNS, Gateway, etc. */  
     while (! displayConnectionDetails())
       {
         delay(1000);
       }
       
         
     cc3000.printIPdotsRev(ip);
     
 //Set up the NFC module
     if (pollFlag == true)
     {
           nfc.begin();
         
           uint32_t versiondata = nfc.getFirmwareVersion();
           if (! versiondata) {
             Serial.print("Didn't find PN53x board");
             while (1); // halt
           }
           // Got ok data, print it out!
           Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
           Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
           Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
           
           // configure board to read RFID tags
           nfc.SAMConfig();
           
           Serial.println("Waiting for an ISO14443A Card ...");
     }
     else {
        Serial.println("Failed to initialize NFC-Reader... Sorry...");
     }
   
     }


Hope I'm not messing up the image-uploads...
(I kept the wiring-colors where I coul for you to see the connections easily)

The boards connected via cables (both separately working)


The boards put together


The boards connected together with the Wifi in the picture.
(You can't see the LED on the CC3000 light up, but I swear it does  ;))


If you need any other pictures or infos, don't hesitate to ask!

greensquirrel

Messed up the Image-upload...
Here they are as links:

The boards connected via cables (both separately working)
http://www.directupload.net/file/d/3740/j3y3tx38_jpg.htm

The boards put together
http://www.directupload.net/file/d/3740/yb9q6qla_jpg.htm

The boards connected together with the Wifi in the picture.
(You can't see the LED on the CC3000 light up, but I swear it does  ;))
http://www.directupload.net/file/d/3740/uorksjrj_jpg.htm


greensquirrel

Ok, I got myself a multimeter today to measure if it is really a problem with the power supply.

With the NFC-Reader running I measured 4.85V on the 5V-Pin and 3.32V on the 3.3V-Pin.
This means, that the CC3000 should have enough Power to run.

So I'm now looking for a possible address collision in the libraries (specifically I2C- and SPI-collisions).
As I'm still new to this, help is really appreciated.

greensquirrel

Morning everyone! What I've found out since yesterday is, that the PN532 uses I2C while the CC3000 uses SPI to communicate. When I looked through the libraries I found out that the PN532 includes Wire.h which gets its address at "nfc.begin();"

In the begin-function in Wire.cpp there is an address transmitted to the function, but I can't find it's source. Is it possible that that address collides with the one the CC3000 uses?

When I uploaded an I2C-Scanner to the UNO, it said that the only device fount is the PN532 on address '0x24'.

I don't really know what to do with that info though, since there are more libraries being included (like 'string.h' which then includes others) and I cant even find these on the Mac I'm working on at the moment...

Hackscribble

Hi greensquirrel

I2C and SPI *should* not interfere with each other.

What results do you get from getFreeRam()?

Regards

Ray
Hackscribble.  Writing about making things
hackscribble@outlook.com

greensquirrel

Hello Hackscribble,
thanks for the Reply!

When I comment out the NFC-initialization,   getFreeRam()   gives out   '150'  .
When I don't comment out the Sketch gets stuck before getting there...

Regards,

Patrick

Edit:
When the NFC-initialization is commented out, the complete Sketch has 24.260 Bytes
When it is not commented out, the size is calculated at 24.982 Bytes

Hackscribble

Quote
When I comment out the NFC-initialization,   getFreeRam()   gives out   '150'  .
When I don't comment out the Sketch gets stuck before getting there...


Just to confirm, with this not commented out

Code: [Select]
Adafruit_NFCShield_I2C nfc(IRQ, RESET);

the program stops before it prints "hello" or before it prints "free RAM"?

Code: [Select]
      Serial.begin(115200);
      Serial.println(F("Hello, CC3000!\n"));     
      Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);


Sounds like you may be running out of memory.  Try putting all remaining string constants into the F() macro, like some of them are at present.  Also try commenting out the servo code as a test.

Hackscribble.  Writing about making things
hackscribble@outlook.com

greensquirrel

I've commented out the Stepper-parts.
The code looks like this now:

Code: [Select]
//WLAN-Libs
   #include <Adafruit_CC3000.h>
   #include <ccspi.h>
   #include <SPI.h>
   #include <string.h>
   #include "utility/debug.h"
   
   //NFC-Libs
   #include <Wire.h>
   #include <Adafruit_NFCShield_I2C.h>
   
   //Motor-Libs
   //#include <Stepper.h>
   
   #define IRQ   (2)
   #define RESET (4)  // Not connected by default on the NFC Shield
   
   Adafruit_NFCShield_I2C nfc(IRQ, RESET);
   
 //Motor-settings
   
   //const int stepsPerRevolution = 180;  // change this to fit the number of steps per revolution
                                        // for your motor
   
   //Stepper Motor(stepsPerRevolution, 6,7,8,9);  // initialize the stepper library on pins 6 through 9:          
   
 //Wifi-settings
 
   // These are the interrupt and control pins
   #define ADAFRUIT_CC3000_IRQ   3  // MUST be an interrupt pin!
   // These can be any two pins
   #define ADAFRUIT_CC3000_VBAT  5
   #define ADAFRUIT_CC3000_CS    10
   // Use hardware SPI for the remaining pins
   // On an UNO, SCK = 13, MISO = 12, and MOSI = 11
   Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                            SPI_CLOCK_DIV2); // you can change this clock speed
   
   #define WLAN_SSID       "mySSID"           // cannot be longer than 32 characters!
   #define WLAN_PASS       "mypassword"
   // Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
   #define WLAN_SECURITY   WLAN_SEC_WPA2
   
   Adafruit_CC3000_Client www;  //defines how we will refer to the cc3000 connection object
   
   // What page to grab!
   #define WEBSITE      "10.2.10.170"  //NOTE: CC3000 doesn't seem to like the default localhost address of 127.0.0.1 - need to enter actual IP
   #define WEBPAGE     "/index.php"
   
   
   //this is the counter that will be used for uploading data
   long pollCounter = 1;
   
   //used for storing data for upload
   //set it to the data type that suits your data
   int
     NFC_ID, Session_ID, UID_final;
   
   //used for commands received from base station
   int
     command_open, command_close;
     
     boolean pollFlag = false;         //tells the sketch whether to poll or not
   
   //declare a variable to hold a numeric IP address
   //can be overridden below if you use lookup
     uint32_t ip = (192L << 24) | (168L<<16) | (1<<8) | 13;
   
   
   /**************************************************************************/
   /*!
       @brief  Initialization of the modules (Motor, Wifi, NFC-Reader)
   */
   /**************************************************************************/
   
   
   void setup(void)
   {
     
     Serial.begin(115200);
     
 //Set up the Motor for the lock
   
     // set the Motor speed at 60 rpm:
     //Serial.println("Starting Motor...");
     //Motor.setSpeed(60);
     //Serial.println("Motor started!");
     
 //Set up the Wifi module
   
     
     Serial.println(F("Hello, CC3000!\n"));
   
     Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);
     
     // Initialise the Wifi module
     Serial.println(F("\nInitializing..."));
     if (!cc3000.begin())
       {
         Serial.println(F("Couldn't begin()! Check your wiring?"));
         while(1);
       }
     
     cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
     
     Serial.println(F("Connected!"));
   
     // Wait for DHCP to complete
     Serial.println(F("Request DHCP"));
     while (!cc3000.checkDHCP())
       {
         delay(100); // ToDo: Insert a DHCP timeout!
       }  
   
     // Display the IP address DNS, Gateway, etc.  
     while (! displayConnectionDetails())
       {
         delay(1000);
       }
       
         
     cc3000.printIPdotsRev(ip);
     
     //Set up the NFC module
     Serial.println("Starting NF-Reader...");
 
     nfc.begin();
         
     uint32_t versiondata = nfc.getFirmwareVersion();
     if (! versiondata) {
       Serial.print("Didn't find PN53x board");
       while (1); // halt
     }
     // Got ok data, print it out!
     Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
     Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
     Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
           
     // configure board to read RFID tags
     nfc.SAMConfig();
     
     Serial.println("NF-Reader started!");
     
     //Text for User to see system is ready
     Serial.println("Waiting for an ISO14443A Card ...");
   }


(Notice I've also taken out the if/else around the nfc-initialization
because I noticed that is not necessary in the current program.)


Could you shortly explain how I correctly use the F() macro and why I should use it?


Oh, btw:
This is what the serial monitor prints out now:

Code: [Select]
Hello, CC3000!

Free RAM: 105

Initializing...
Hello, CC3000!

Free RAM: 105

Initializing...
Hello, CC3000!

Free RAM: 105

Initializing...
Hello, CC3000!

Free RAM: 105

Initializing...
Hello, CC3000!

Free RAM: 105

Initializing...

(Repeat to infinity)


Thanks for your help on this, Ray!

Hackscribble

Quote
Could you shortly explain how I correctly use the F() macro and why I should use it?


When you have a string constant in a program, e.g. Serial.println("hello world");, the string is copied at run time into SRAM as well as being in the Flash program code memory.  The F() macro stores  and accesses the string in program memory, saving SRAM.

http://playground.arduino.cc/Learning/Memory

Some of your code already uses the F() macro, but there are some statements like this where you could add it:

Code: [Select]
//Serial.println("Starting NF-Reader...");
Serial.println(F("Starting NF-Reader..."));


I'll have a look at your latest code shortly, but it looks like the Arduino is still resetting at cc3000.begin().

Code: [Select]
Hello, CC3000!

Free RAM: 105

Initializing...
Hello, CC3000!



Hackscribble.  Writing about making things
hackscribble@outlook.com

greensquirrel

Ray, you're awesome!!!

it really seems to have been the SRAM overflowing!

I've used the  F()-macro  like this:
Code: [Select]
void setup(void)
    {
     
      Serial.begin(115200);
     
  /*Set up the Motor for the lock
   
      // set the Motor speed at 60 rpm:
      Serial.println("Starting Motor...");
      Motor.setSpeed(60);
      Serial.println("Motor started!");*/
     
  //Set up the Wifi module
     
     
      Serial.println(F("Hello, CC3000!\n"));
   
      Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);
     
      // Initialise the Wifi module
      Serial.println(F("\nInitializing..."));
      if (!cc3000.begin())
        {
          Serial.println(F("Couldn't begin()! Check your wiring?"));
          while(1);
        }
     
      cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
       
      Serial.println(F("Connected!"));
   
      // Wait for DHCP to complete
      Serial.println(F("Request DHCP"));
      while (!cc3000.checkDHCP())
        {
          delay(100); // ToDo: Insert a DHCP timeout!
        } 
   
      // Display the IP address DNS, Gateway, etc.   
      while (! displayConnectionDetails())
        {
          delay(1000);
        }
       
         
      cc3000.printIPdotsRev(ip);
     
      //Set up the NFC module
      Serial.println(F("Starting NF-Reader..."));
 
      nfc.begin();
         
      uint32_t versiondata = nfc.getFirmwareVersion();
      if (! versiondata) {
        Serial.print(F("Didn't find PN53x board"));
        while (1); // halt
      }
      // Got ok data, print it out!
      Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
      Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
      Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
           
      // configure board to read RFID tags
      nfc.SAMConfig();
     
      Serial.println(F("NF-Reader started!"));
     
      //Text for User to see system is ready
      Serial.println(F("Waiting for an ISO14443A Card ..."));
    }


and now the serial monitor says:
Code: [Select]
Hello, CC3000!

Free RAM: 203

Initializing...
Connected!
Request DHCP

IP Addr: 10.2.10.64
Netmask: 255.255.255.0
Gateway: 10.2.10.254
DHCPsrv: 10.2.10.254
DNSserv: 10.2.20.251
192.168.1.13Starting NF-Reader...
Found chip PN532
Firmware ver. 1.6
NF-Reader started!
Waiting for an ISO14443A Card ...
Success: 1
Found an ISO14443A card
  UID Length: 4 bytes
  UID Value: 0x13 0x94 0x26 0xD4

UID Feld 0 hat Wert: 19
UID Feld 1 hat Wert: 148
UID Feld 2 hat Wert: 38
UID Feld 3 hat Wert: 212
UID Feld 4 hat Wert: 0
UID Feld 5 hat Wert: 0
UID Feld 6 hat Wert: 0
UID Feld 7 hat Wert: 2
UID_final: 419
Seems to be a Mifare Classic card (4 byte UID)
Trying to authenticate block 4 with default KeyA value
Sector 1 (Blocks 4..7) has been authenticated
Reading Block 4:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................



I can even read TAGs while being connected to the WLAN  XD

I've read the tutorial in your link. This works only for strings, right?
So if I've got any other type of variable, I have to use PROGMEM. But from reading up on those two I get the impression
that they can only be used on variables that don't change while the program is running.

Do you by any chance know a good tutorial (except the ones on this site ^^) which teaches how to make arduino-code more compact?

Thank you so much, again!!

Hackscribble

I took your code from reply #7.  After installing CC3000 and NFC libraries, it compiled with a couple of changes. 

I think you cut off loop() when you posted the code :)

But I had to comment out displayConnectionDetails() which the compiler could not find.

Anyway, the program compiled and loaded.  I don't have a CC3000 module to test with, so when I run it, it stops having printed "initialising".

However, it is showing 768 bytes of free memory just before that. 

So, I'm wondering about that displayConnectionDetails() function.  Where is it in your program, and does it have a lot of strings in it?

Memory shortage may not be the issue, but it would be good to eliminate it as a possibility.
Hackscribble.  Writing about making things
hackscribble@outlook.com

greensquirrel

The whole sketch is 4 tabs big.
Do you want me to post all of it, so you can have a look?

Hackscribble

Our posts crossed. Glad to hear it is working :)

Might be worth still looking into that display connection details function, since it seems to be using up a lot of SRAM which you might need as you develop the program further.  You can attach the files to a post, rather than have to cut and paste them.  Look under Additional Options below the post text entry box.

As well as the pages on this site about F(), I found this other page which covers some other aspects.

https://learn.adafruit.com/memories-of-an-arduino/optimizing-sram

Hackscribble.  Writing about making things
hackscribble@outlook.com

greensquirrel

So much input ^^

I've attached the four files. Here's a short description on what they do:
1. Main file containing setup() , loop() and the functions for the CC3000
2. File that contains the functions for the servo to move
    (really simple right now, but the servo isn't implemented, so it maybe will grow later on)
3. Here the reading of the NFC-tags happens
4. Here, the read data is supposed to be sent to a DB where it can be called from using a webinterface (which already works)
    (Note that I haven't laid a finger on this tab since trying to connect the hardware ^^)

I'll read up on SRAM now!
And thanks again, this is really making my day  XD

Hackscribble

There are some strings in files 2 and 3 that you could apply F() to.  It's already been done in file 4.  And I can see that function now, at the bottom of your main program - already macroed :)

See what free memory count you get after updating those files.  Then try adding the stepper code back in, checking free memory.

Also check program code size.  After compiling, you'll see a message like this in the IDE window.

Quote
Binary sketch size: 21,206 bytes (of a 32,256 byte maximum)

Hackscribble.  Writing about making things
hackscribble@outlook.com

Go Up