4:23 pm
April 17, 2016
Okay, so I'm using a Due for its horsepower but need some persistent storage for a few kB of coefficients. The Due has no EEPROM, but I found a nifty and easy to use library that allows programmatic read/write to the Due's program-storage flash instead. Win! See https://github.com/sebnil/DueF.....ashStorage
I'm using LabVIEW 2014 64-bit.
I'm now in the throes of importing that library into subVIs that I'd very much like to share with the community. I've gone through the steps in the User Manual and performed the following steps:
- Installed the library in the IDE and ensured its example code compiles properly.
- Copied your Template directory into one alongside it (C:\Program Files\National Instruments\LabVIEW 2014\vi.lib\Aledyne-TSXperts\Arduino Compatible Compiler for LabVIEW\addons\Arduino Due Flash Storage),
- Created front panels for the read and write functions, and saved them as password-protected (password for each in the attached .zip is "hamster")
- Copied the C code to the libraries subfolder,
- Edited Translator.vi so it has cases for each of the two functions, and
- Created test VIs for the two functions.
Problem: The Compiler's "Arduino Code" check-function reports for both of my test VIs:
Error in dueFlashStorage [test .vi name]: "dueFlashStorage.lvlib:[function name]" not supported
For example, loading dueFlashStorage read test.vi into the Compiler and selecting the "Arduino Code" function from the Compiler menu results in Error in dueFlashStorage read test.vi: "dueFlashStorage.lvlib:read" not supported. Similarly for the write test VI.
...From poking around, one guess is that the Compiler may be calling another Translator.vi from elsewhere rather than using the Translator.vi in the directory. I've tried doing things with the Translator.vi included in the .lvlib (as per the Digilent Analog Shield example; I note there's no libraries subdirectory for that one?) and not-included (as per the Template example). Either that, or it's maybe it's not finding what it needs in the libraries subfolder, or maybe there's a typo (case issue?) that eludes me. I've been careful with case and naming hygiene but let's just say there's a reason I prefer to use LabVIEW over textual languages.
So, any ideas what I'm doing wrong?
Many thanks in advance!
9:37 pm
March 12, 2015
Its not super clear in the documentation but the lvlib must be the same name as the folder name. You should see the other addons and Template follow that naming convention. We have a pending update to the user manual that clarifies that.
Also, for your information, there is already built in capability in the Utilities palette to write to program memory at compile time and read from program memory at run-time. This is good for lookup tables, coefficients, etc. but does not allow you to write to program memory at run-time. So depending on what you need, this may already work for you.
11:25 pm
April 17, 2016
Renaming the folder and rebuilding the .lvlib did the trick! Thanks thanks thanks.
The application I'm working on to write its coefficients in the field, so doing it at compile time won't do the job. But thanks for that suggestion!
I'll post back once this library is tested and doing what it's supposed to do.
11:37 pm
April 17, 2016
Hm, just noticed something.
Here's what the Arduino compiler reports for the write function. The definition for this function in the .h file is:
boolean write(uint32_t address, byte value);
A screen-snap of the test VI is attached.
And the reported code is:
#include "LVArray.h"
#include "A4Lhelper.h"
#include "DueFlashStorage.h"
void setup()
{
unsigned char Const136;
unsigned long Const111;
Const136 = 1;
Const111 = 0;
boolean Node342Out;
Node342Out = write(Const207,Const136);
}
void loop()
{
}
Inspecting that, I'm wondering: What is Const207? I would expect the call to be write(Const111, Const136). Is something wrong?
1:23 am
March 12, 2015
scottj said
Inspecting that, I'm wondering: What is Const207? I would expect the call to be write(Const111, Const136). Is something wrong?
Const207 could be the error input wire unless you have another unwired input. You need to index the correct input in the Translator to get Const111. The input ordering should correlate to the order shown in the context help.
2:32 am
April 17, 2016
Hm, to my eye the Arduino code says Const207 is what is being passed as the address parameter to the write function. That doesn't make sense... and it really doesn't make sense that the error cluster is being passed as the address, which is expecting a uint32.
Const111 is shown by the compiler's output as containing the value 0, which is the constant I wired to the address. I tried changing it to a different value and Const111 changed accordingly. So Const111 should be what is fed to the write function as the address. Const207, whatever it is, remains puzzling.
I'm being cautious about this since I'll be writing to flash... one wrong move and maybe bad things could happen. If the Const111/Const207 mystery is nothing to worry about, that's fine, just let me know.
The context help is:
There's a similar puzzle for the read test VI. Here is the definition of the read function from the .h file:
byte read(uint32_t address);
And here is what is returned by the Compiler as the Arduino code for the read test VI:
#include "LVArray.h"
#include "A4Lhelper.h"
#include "DueFlashStorage.h"
void setup()
{
unsigned long Const111;
Const111 = 0;
unsigned char Node126Out;
Node126Out = read(error_in__no_error__76);
}
void loop()
{
}
...So once again Const111 contains the value I'd expect to see passed as the address, but what's actually being passed to the function is error_in__no_error__76, whatever that is.
If this is okay, I'll just press on! Thanks again.
3:36 am
April 17, 2016
Actually, it's starting to dawn on me what is going on and what I need to do about it: You provide the Arduino Code functionality for a reason, and part of that is to check that variables are being routed to the correct places in the function calls. What I'm concluding is that this mapping is not correct for my VIs yet. So, I'll turn the crank some more and will let you know how it goes.
3:43 am
April 17, 2016
Much better now:
#include "LVArray.h"
#include "A4Lhelper.h"
#include "DueFlashStorage.h"
void setup()
{
unsigned long Const111;
Const111 = 0;
unsigned char Node126Out;
Node126Out = read(Const111);
}
void loop()
{
}
and
#include "LVArray.h"
#include "A4Lhelper.h"
#include "DueFlashStorage.h"
void setup()
{
unsigned char Const136;
unsigned long Const111;
Const136 = 1;
Const111 = 9;
boolean Node342Out;
Node342Out = write(Const111,Const136);
}
void loop()
{
}
Bliss.
5:21 pm
April 17, 2016
I'll go through this process a few more times with some other libraries and will document the steps, focusing on where I get confused.
I'll send that on in case it might help others get up to speed with this capability. It really is powerful and, as I'm learning, it's not difficult at all.
Thanks again for all your helpfulness!
10:25 pm
April 17, 2016
Next challenge: getting an application compiling.
I started with my read-test VI from post 4 in this thread. The compiler reports:
1.0.0.21, Arduino Due (Programming Port)
Loading configuration...
Initializing packages...
Preparing boards...
Verifying...
C:\Users\S\AppData\Local\Temp\58e9973bb6e2e908c6c199f5a9d39075.tmp\temp\temp.ino: In function 'void setup()':
temp:9: error: 'read' was not declared in this scope
Node126Out = read(Const111);
^
Multiple libraries were found for "DueFlashStorage.h"
Used: C:\Users\S\Documents\Arduino\libraries\DueFlashStorage
Not used: C:\Users\S\Documents\Arduino\libraries\DueFlashStorage-master
Not used: C:\Users\S\Documents\Arduino\libraries\Arduino_Due_Flash_Storage
exit status 1
'read' was not declared in this scope
Interestingly, seems it did not find the .h library I copied into the libraries folder in which I created the subVIs, .lvlib, Translator.vi, etc.
So, two fresh mysteries, to me at least: (1) the read function is not recognized by the compiler, and (2) the compiler is looking in the Arduino IDE folder and not in the libraries subfolder of the folder containing the subVI and its associated .lvlib.
EDIT: Unsurprisingly, I also get the same error for the write subVI.
10:53 pm
March 12, 2015
First problem is that you have multiple copies of your library in the libraries folder (DueFlashStorage, DueFlashStorage-master, Arduino_Due_Flash_Storage). This explains the warning and although it would probably work, you should remove the duplicates. Keep in mind the Compiler will automatically copy over the one you put in the addons folder so you dont need to add it separately to the Arduino libraries folder.
For the actual compilation issue, you have not created an object in your translator. Take a look at the example that probably ships with the library. You usually need to create the object first, like this:
DueFlashStorage storage;
Then you need to call the read method like this:
storage.read();
12:54 am
April 17, 2016
Hm.
I'm not finding anything like that in the Template example. But in the Digilent Analog Shield example, just before the terminating #endif in analogShield.h, there's the following line:
extern analogShield analog;
In the shipping bundle for the dueFlashShield Arduino library (https://github.com/sebnil/DueF.....ashStorage), there's no such line in the .h file. Instead the examples put at their beginning, right after their #include statement,
DueFlashStorage dueFlashStorage;
...which I presume accomplishes something of the same sort. Being a simple physicist, I don't quite grasp the difference between these two approaches, or where best-practice would dictate one to create the object, as you say. In any case:
After removing all my duplicative libraries, leaving only the one in the libraries folder adjacent to my .lvlib, and taking an approach similar to what was used for the Analog Shield (which is, after all, one of your shipping examples), I tried adding to my dueFlashStorage.h:
extern DueFlashStorage dueflash;
...and changing the calls in my Translator.vi accordingly, for example:
Unfortunately this results in a compilation error:
1.0.0.21, Arduino Due (Programming Port)
Loading configuration...
Initializing packages...
Preparing boards...
Verifying...
sketchtemp.ino.cpp.o: In function `setup':
C:UsersSAppDataLocalTemp58e9973bb6e2e908c6c199f5a9d39075.tmptemp/temp.ino:9: undefined reference to `dueflash'
collect2.exe: error: ld returned 1 exit status
exit status 1
Error compiling for board Arduino Due (Programming Port).
Removing the "extern" keyword, deleting the duplicative library folder the Compiler created again in C:UsersSDocumentsArduinoLibraries, and recompiling results in a different error:
1.0.0.21, Arduino Due (Programming Port)
Loading configuration...
Initializing packages...
Preparing boards...
Verifying...
librariesdueFlashStorageDueFlashStorage.cpp.o: In function `DueFlashStorage::readAddress(unsigned long)':
C:UsersSDocumentsArduinolibrariesdueFlashStorage/DueFlashStorage.cpp:3: multiple definition of `dueflash'
sketchtemp.ino.cpp.o:C:UsersSDocumentsArduinolibrariesLVArray/A4Lhelper.h:28: first defined here
collect2.exe: error: ld returned 1 exit status
exit status 1
Error compiling for board Arduino Due (Programming Port).
I'm pretty sure my issue relates to my unfamiliarity with C++ syntax, so I'm hoping it's obvious to you!
Thanks again for all your helpfulness.
1:32 am
March 12, 2015
You probably need to brush up on C++ but generally you need to create the object first. This is accomplished with the line:
DueFlashStorage dueFlashStorage;
Just like the analog shield example you can include this line after the #include. But notice the name of the object is "dueFlashStorage". So that means for your function calls you need to use the same object name. So use dueFlashStorage.read().
2:01 am
April 17, 2016
Getting there... step by step... Seems there's more to this than the user manual shows...
I'm not quite clear where that line is supposed to be inserted. So, first I tried adding the line
DueFlashStorage dueFlashStorage;
after the #include in the .h file in the libraries sub-folder of my add-on's folder, taking care to first delete the library directory the Compiler copied over to the Arduino folder. I made sure no other similar lines were in the .h or .cpp file. I then modified my Translator.vi accordingly:
But compiling results in:
1.0.0.21, Arduino Due (Programming Port)
Loading configuration...
Initializing packages...
Preparing boards...
Verifying...
C:\Users\S\AppData\Local\Temp\58e9973bb6e2e908c6c199f5a9d39075.tmp\temp\temp.ino: In function 'void setup()':
temp:9: error: 'dueFlashStorage' was not declared in this scope
Node126Out = dueFlashStorage.read(Const111);
^
exit status 1
'dueFlashStorage' was not declared in this scope
So the I un-did that change and put the "DueFlashStorage dueFlashStorage;" line in the .cpp file again. This time compilation results in:
1.0.0.21, Arduino Due (Programming Port)
Loading configuration...
Initializing packages...
Preparing boards...
Verifying...
In file included from C:\Users\S\AppData\Local\Temp\58e9973bb6e2e908c6c199f5a9d39075.tmp\temp\temp.ino:3:0:
C:\Users\S\Documents\Arduino\libraries\dueFlashStorage/DueFlashStorage.h:21:1: error: 'DueFlashStorage' does not name a type
DueFlashStorage dueFlashStorage;
^
C:\Users\S\AppData\Local\Temp\58e9973bb6e2e908c6c199f5a9d39075.tmp\temp\temp.ino: In function 'void setup()':
temp:9: error: 'dueFlashStorage' was not declared in this scope
Node126Out = dueFlashStorage.read(Const111);
^
exit status 1
'dueFlashStorage' was not declared in this scope
Thoughts? In case it helps, I attach a .zip of my add-on directory.
4:21 am
March 12, 2015
No, you should not be modifying the .cpp or .h files of the library itself. All the work is done in the Translator. The key here is to generate sketch level code. So even before compiling you should be taking the Arduino code output from the Compiler with your dueFlashStorage read test.vi and write test vi and copy those into the Arduino IDE. If those don't compile then you know you have done something wrong. Unfortunately the manual cannot go into all the details since this is sketch level code generation so thats why it is an advanced feature that requires some C/C++ knowledge.
In any case, I have modified your Translator so it compiles. You need to create the object at the sketch level, so to do this dueFlashStorage is placed globally under the include.
15
1 Guest(s)