Add SPI.h to custom Arduino Library - Page 1
Forum section: electronics / general

author: tomshirvo
author_rank: Regular Contributor
timestamp: November 10, 2014, 11:04:06 am
content: Hi All,Making a custom library for a SPI flash Chip I have. I got it all working with Arduino just using functions. I am now trying to make my first library and I am trying to include SPI.h but it comes up saying can't file file.It might be a little rough at the moment but it is because I am learning. If you can give me any pointers about what I have done I would very much appreciate it.I have tried to include the SPI.h in both .h and .cpp files but doesn't work. I need to be able to call SPI.begin and SPI.transfer functions in this library.my .h fileCode:#ifndef flashMemory_h#define flashMemory_h#if defined(__AVR__)#include "Arduino.h"#include "hardware/avr/HW_AVR_defines.h"#elif defined(__arm__)#include "Arduino.h"#include "hardware/arm/HW_ARM_defines.h"#endifclass flashMemory{public:flashMemory(uint8_t CE);flashMemory(uint8_t CE,uint8_t SPIClock);voidbegin();boolean bulkErase();boolean writeEnable();boolean writeDisable();boolean verifySR(uint8_t sRegister, uint8_t value);void timeOut(uint16_t timeOut);protected:uint8_t _pinCE, _SPIClock;uint16_t _timeOut;boolean _SPIClockSelect;void_SPIstart(uint8_t rate);};#endifmy cpp fileCode:#include "flashMemory.h"#if defined(__AVR__)#include "hardware/avr/HW_AVR.h"#elif defined(__arm__)#include "hardware/arm/HW_ARM.h"#endifflashMemory::flashMemory(uint8_t CE){_SPIClockSelect = false;_pinCE = CE;}flashMemory::flashMemory(uint8_t CE, uint8_t SPIClock){_SPIClockSelect = true;_pinCE= CE;_SPIClock = SPIClock;}void flashMemory::begin(){if(_SPIClockSelect){_SPIstart(_SPIClock);}else_SPIstart(SPI_CLOCK_DEFAULT);}boolean flashMemory::bulkErase(){writeEnable();digitalWrite(_pinCE,LOW);SPI.transfer(0xC7);digitalWrite(_pinCE,HIGH);uint32_t start = millis();boolean error = false;while(error = verifySR(0,1) == true && millis() - start < _timeOut){}return error;}void flashMemory::timeOut(uint16_t timeOut){_timeOut = timeOut;}//Write Enable//This enables data to be send to the Flash chip to write data.boolean flashMemory::writeEnable(void){uint32_t time = millis();boolean error = false;do{digitalWrite(_pinCE,LOW); //Select the Flash chip on the SPI busSPI.transfer(0x06); //WREN (Write Enable)digitalWrite(_pinCE,HIGH); //deselect the Flash chip on the SPI bus}while(error = verifySR(1,1) == false && millis() - time < _timeOut); //Retry until the change was madereturn error;}//Write Disable//This disables data to be send to the Flash chip to write data.boolean flashMemory::writeDisable(){uint32_t time = millis();boolean error = false;do{digitalWrite(_pinCE,LOW); //Select the Flash chip on the SPI busSPI.transfer(0x04); ///WRDI (Write Disable)digitalWrite(_pinCE,HIGH); //deselect the Flash chip on the SPI bus}while(error = verifySR(1,1) == false && millis() - time < _timeOut); //Retry until the change was madereturn error;}//Verify Status Register//Send the register location and the value you are expecting.//This will return a boolean for the resultboolean flashMemory::verifySR(byte sRegister, byte value){uint32_t time = millis();byte error = 0; //Hold the returned value from the status register.do{digitalWrite(_pinCE,LOW); //Select the Flash chip on the SPI busSPI.transfer(0x05); //Send the status register read instructionerror = SPI.transfer(0xff); //Read the returned data from the chipif(error == 255){ //If error code is 255 then show user in serial monitor}digitalWrite(_pinCE,HIGH); //deselect the Flash chip on the SPI bus}while(error == 255 && millis() - time < _timeOut); //do it once and if error do it until no error.byte _value = 0; //The value collected in the required register position_value = bitRead(error,sRegister); //get the value returned in that positionif(_value != value){ //return if it was the correct response or not.return false;}else if(_value == value){return true;}}

author: sleemanj
author_rank: Super Contributor
timestamp: November 10, 2014, 11:18:39 am
content: The Arduino IDE messes about with includes, effectively, it pre-processes your code before compiling, and inserts various stuff, creating a source code tree in a (usually temporary) folder which it then compiles, the libraries which the IDE chooses to put into the source code tree depend on what it detects is being used (by way of includes), it's all pretty brittle if you ask me, but anyway.As a result, what you think (as a C programmer) should work, may or may not do what you think it should be doing when the Arduino IDE has done with it. In the IDE's "preferences.txt" file (if you open the Preferences dialog in the IDE it tells you where this is) there is an option "build.path" (this is not exposed in the GUI, you have to edit the file), set this to some specific path, reload the IDE, then compile your sketch, once done (regardless if successful or not) you can have a look at what the IDE slapped together and actually tried to compile in your specified path.From memory (and I might be misremembering), I don't think you can actually include one library (SPI in this case) from inside another library's library code, I don't think the IDE looks deep enough to include the depended upon library in the temporary source code tree for compilation. The typical way to do it is, to include the depended library from within the example sketches you provide with the library themselves, ie, at the same place you include your library itself. This isn't TOO bad a solution, because most people using the Arduino IDE are just going to copy-paste your example(s) to use as a boilerplate anyway.

author: tomshirvo
author_rank: Regular Contributor
timestamp: November 10, 2014, 11:59:24 am
content: Thanks for the replay.The only problem is that I can't use the spi.transfer doesn't work in my library. So it sounds like I can't use SPI in libraries.

author: Unknown
author_rank: Unknown
timestamp: November 10, 2014, 01:26:10 pm
content: Quote from: tomshirvo on November 10, 2014, 11:59:24 amYou can use spi.transfer in your own libraries - I've literally just now finished writing a library that uses it. Youjust can'tcan't justinclude the SPI library in your library for the reasons sleemanj mentioned; you have to #include it in your main sketchtoo.Yes, it is a bit of a dumb limitation to someone coming from proper C, but it does make a twisted sort of sense in Arduino-land (if you google around you'll see some of their arguments).(edit, asnoted.)

author: zapta
author_rank: Super Contributor
timestamp: November 10, 2014, 04:27:05 pm
content: How do you install your library, using the Arduino IDE Add Library? If so, they the manual way as explained in this link. It puts the library in a different location.https://code.google.com/p/u8glib/wiki/u8glibAs others said, Arduino libraries are problematic.

author: dannyf
author_rank: Super Contributor
timestamp: November 10, 2014, 10:59:50 pm
content: The complexity of managing a multi file project in the arduino ide is something that should be addressed. A typical avr or pic project for me has 20 - 30 modules - .c and .h files and to manually open them up in the arduono ide to use them in the project is just tedious.

author: Unknown
author_rank: Unknown
timestamp: November 11, 2014, 12:38:03 am
content: Quote from: zapta on November 10, 2014, 04:27:05 pmAt least in 1.0.5/1.0.6, both ways end up sticking the library in the same place - in //Arduino/libraries/. The only other valid library path in the Arduino environment is wherever the Arduino system libs (e.g. Arduino.h) are installed, which is O/S-dependent.FWIW, a passably-OK explanation of how to use other libraries in your library can be foundhere(no connection, just found it on a quick google).

author: tomshirvo
author_rank: Regular Contributor
timestamp: November 11, 2014, 01:46:04 am
content: So even adding the #include <SPI.h> in the sketch didn't work.I then tried to put it in the flashMemory.h file in the below location and it worked after that.Code:#if defined(__AVR__)#include "Arduino.h"#include "SPI.h"#include "hardware/avr/HW_AVR_defines.h"#elif defined(__arm__)#include "Arduino.h"#include "SPI.h"#include "hardware/arm/HW_ARM_defines.h"#endifThanks for all the help.

author: Unknown
author_rank: Unknown
timestamp: November 11, 2014, 01:57:23 am
content: Sorry, I just realised my post last night wasn't clear (it was late!) - you need to include SPI.h inboththe sketch & your library. I've edited it to make it clearer.Glad you got it sorted.

author: djacobow
author_rank: Super Contributor
timestamp: November 11, 2014, 02:49:17 am
content: This. That's the brain damage of the Ard environment. Includes in libraries and other files in your sketch will mysteriously not find certain headers (mostly from "standard" Ard libraries) that are not also included in the main sketch.Why? I dunno. Not a good reason, I'm sure.I'm all for Ard being simple and all, but certain things they do to make life easier actually make it weirder. I'm no fan of setup() and loop(). main() is just fine, thanks. I can make my own setup and loop if I need them. Oh, and the pre-declared objects for things like Serial just bug me. Sure, it saves the beginner from having to write one mysterious line of code, but it also inhibits them from learning how stuff works.Quote from: Tac Eht Xilef on November 11, 2014, 01:57:23 am

author: westfw
author_rank: Super Contributor
timestamp: November 12, 2014, 09:44:21 am
content: QuoteBecause the IDE scans the include statements in the .ino files, and uses that information to build a set of "-I /long/path/to/librarydirectory" options for the compile line. It doesn't do that pre-processing for .cpp or .c files, so things included only by library .cpp files don't have their paths added to the command line.It would certainly be nice if the top-level library directories were also put in the search path, so you could do things like:#include "SPI/spi.h" instead of #include "/Applications/arduino/Arduino-1.0.6.app/Contents/Resources/Java/libraries/SPI/spi.h"Note that the default behavior is to require that YOU manually specify the full path, and the Ard IDE's actions are not significantly different than other IDEs that would have you set up library dependencies from some menu...

author: djacobow
author_rank: Super Contributor
timestamp: November 17, 2014, 01:36:53 am
content: Quote from: westfw on November 12, 2014, 09:44:21 amUh huh. If they wanted to be really fancy, they could even provide a library "install" facility, where you click a menu option, point the IDE at a zip file and, voila, files are just magically copied to the right places in <sketchbook>/libraries and those include paths are automatically searched. The problem is that the IDE needs to know to rebuild the .cpp files, too, hence the scanning. But they could just scan all your project files, or else provide a checkbox list of "features" to include, like most other IDEs.The odd think about Ard is that they have not really made serious progress in the IDE in years.Quote from: westfw on November 12, 2014, 09:44:21 amBut the Ard folks started with a mission to make something easy and accessible, so I think it's perfectly reasonable to hold them to a higher standard of simplicity.

author: westfw
author_rank: Super Contributor
timestamp: November 17, 2014, 08:15:11 am
content: QuoteFor the "sketch" writers. If you're writing libraries, you're expected to put up with more demanding requirements.Personally, I am pretty sure that I don't want to compile every library I've ever installed, for each sketch.Modern "professional" IDEs seem to be starting to copy all library files 'checked' into each project that uses them. While I appreciate the benefits from a version control perspective, I don't think I like this very much either :-(Whatever. I have now asked:https://github.com/arduino/Arduino/issues/2448QuoteWhereas, in a similar time interval, MPLAB became MPLABX, AVR Studio became Atmel Studio, and CCS became Eclipse-based; massive improvements that everyone is just thoroughly enthusiastic about? :-)Also, it's not true. There have been pretty substantial changes in the Arduino IDE "recently." Being able to install third party libraries (and boards/etc) in the user documents/Arduino/ folder instead of deep inside the IDE install was one of them, but there's also the "variants" modification in 1.0 that allows support of significantly different AVRs, and the "platforms" modification in 1.5 that allows support of other entirely different processors.

author: djacobow
author_rank: Super Contributor
timestamp: November 19, 2014, 06:53:32 am
content: Quote from: westfw on November 17, 2014, 08:15:11 amActually, with a proper make facility or something like ccache, it could be pretty painless. And really, the libraries do not need to be compiled for every sketch, but they do need to be compiled for every variant and platform. That could be done at install time.I've never dug unto it, but the Ard environment doesn't even seem to track dependencies at all. At least on Windows, it seems to rebuild everything each time. I think on Linux it seems a bit smarter, but I haven't paid close attention.Quote from: westfw on November 17, 2014, 08:15:11 amYeah, I'm no fan of that, either, but I get it.Quote from: westfw on November 17, 2014, 08:15:11 amOh, they've made improvements. But there have been really few releases. 1.0.x is still officially current, 1.5.x has been in beta for what seems like years, maybe actual years?But the things that continue to bug me are the feeble text editor, half-baked syntax highlighting, atrocious and non-changeable font. (my eyes are failing prematurely and l's and 1's look the same to me). There are some really good monospace fonts out there for programming these days.It also drives me bonkers that they close the serial window every time you upload. If you are using serial for upload, then, ok, how about disconnecting the serial monitor and reconnecting it after the upload? And if you are using a programmer to upload, then you can just leave it be.But it's free and I use it all the time for AVR work because the unzip-and-run convenience is pretty hard to beat. People complains about the Ard functions, but there's nobody forcing you to use them.

author: westfw
author_rank: Super Contributor
timestamp: November 19, 2014, 11:37:31 am
content: QuoteThey're changeable. Just not "easily." You have to manually edit the relevant preferences and/or "theme" files.

author: Mechatrommer
author_rank: Super Contributor
timestamp: November 20, 2014, 11:07:27 pm
content: sure you already or will found the solution long time ago, only if...1) you dont insist on running things on "linux"...2) you choose to become arduino the "IDE" developement team, not just a mere user.arduino the "IDE" is an inevitable crap. a broken system that is well maintained and supported by many people... how irony...*broken in the sense that the compile time is exponential compared to other IDE, thats the most killing aspect. and managing mega project many files problem is the second... imho, and this library problem? this is probably the third or forth or fifth.. small problem... small problem...