Is there a #define _KEYWORD_ in arduino.h to check against? - arduino

I would prefer to use standard Arduino API's if they are available. I need a way to check if arduino.h is present. If it is not available (i.e. executing code on BeagleBone Black), then I can use my own functions.

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
Taken from: http://www.arduino.cc/en/Main/ReleaseNotes [internals]

Related

Optimize library Arduino : undefined reference

The development for embedded system impose an other way to code.
In the goal to minimize size of my library named RF24Wave, I would adapt the structure of my main class.
The idea is to declare some functions only with the presence of certain #define during the inclusion of my library in main program.
The popular library, like MySensor use this way to minimize memory footprint.
So, I have two files for my library :
RF24Wave.h : header file which contain function declarations
#ifndef __RF24WAVE_H
#define __RF24WAVE_H
#include <arduino.h>
...
class RF24Wave
{
public:
/****** Common functions ******/
void begin();
#if !defined(WAVE_MASTER)
/****** Node functions ********/
void connect();
#else
/****** Master functions ******/
void printNetwork();
#endif
private:
bool synchronized = false;
}
RF24Wave.cpp: source file which contain function definitions
#include "RF24Wave.h"
void begin()
{
//Body of my function
}
#if !defined(WAVE_MASTER)
void connect()
{
//Body of my function
}
#else
void printNetwork()
{
//Body of my function
}
#endif
Secondly, I include this library in my main sketch named master.cpp, with #define WAVE_MASTER:
master.cpp: main sketch
#include <RF24.h>
#include <RF24Network.h>
#include <RF24Mesh.h>
#include <SPI.h>
#define WAVE_MASTER
#include <RF24Wave.h>
#include "master.h"
// Configure the chosen CE, CSN pins
RF24 radio(CE_PIN, CSN_PIN);
RF24Network network(radio);
RF24Mesh mesh(radio,network);
RF24Wave wave(network, mesh);
uint32_t displayTimer = 0;
void setup()
{
Serial.begin(115200);
wave.begin();
}
void loop()
{
wave.listen();
wave.printNetwork();
}
The goal is to include only master functions when #define WAVE_MASTER is defined in the main sketch.
However, during the compilation of my main sketch, I have a linking error
In function `main':
undefined reference to `RF24Wave::printNetwork()'
collect2: error: ld returned 1 exit status
*** [.pioenvs/uno/firmware.elf] Error 1
I compiled with PlaformIO Core 1.7.1 /Atom 1.13.0
Finally, the reason of this problem is the scope of #define.
The solution of this problem is added build flags to gcc-compiler !
If you use combo PlatformIO/Atom, you can add this line into this
config file platformio.ini :
build_flags = -D$NAME_DEFINE
In our case :
build_flags = -DWAVE_MASTER
After adding this line, the building seems work fine !
In addition, with this selective #define, my library has reduced footprint memory more than 10% !
Many thanks for your help.
If you add your library in the arduino IDE as it is described here it just consists in linking another project to your library functions. It's not a static library (see static and dynamic libraries). Then I think it's not necessary to worry about its size since the compiler will embed your library functions only if you use them.
Try opening any example (AnalogReadSerial), compile it. Then Sketch->Add a library->SPI. Compile it again, the size does not change. Try to call SPI.begin() in the setup function, the size increases. Add a call to SPI.setBitOrder(MSBFIRST);, the size increases again. Add another call to SPI.setBitOrder(MSBFIRST);, the size increases again, but not by the same amount since it contains only one setBitOrder definition and two calls to the setBitOrder function.
That's not exactly true for all libraries since some constructs could force the compiler to embed some code or allocate memory even if the variable is not used (see for instance volatile variables).
So regarding your size issue, you'd probably only need to use one #define MASTER, write the master code in setup and loop functions surrounded by #ifdef MASTER and the slave code surrounded by #else...#endif. The compiler will include the function definitions that both master or slave use.
So, with your answer, I found the solution !
The problem is the scope of #define. During the building, the first source code compiled is the main sketch ! So, it includes the correct #define WAVE_MASTER in RF24Wave.h of master.cpp. But, the compiler don't take this define into account of other source files. So, during the compilation of RF24Wave.cpp, #define WAVE_MASTER wasn't defined for this source file.
The solution consist to add an extra gcc-flag to define WAVE_MASTER for all source and header files.
With PlatformIO/Atom, it's possible in adding this line in config file platformio.ini
build_flags = -DWAVE_MASTER
Finally, your config file should look like this :
[env:uno]
platform = atmelavr
board = uno
framework = arduino
build_flags = -DWAVE_MASTER
With this solution, it is no longer necessary to add #define WAVE_MASTER in your header file, because this is the compiler which add it for you.
In addition, this optimization has been reduced more than 10% memory usage, because like this is a big class object, the compiler builded all functions. With selective define, the compiler will build only useful functions.

how to transmit with Nreadings>5

I am trying to set Nreadings in the Oscilloscope header file in tinyos above 5,say I set it at 6. When I do this, I notice that transmissions cease that is the green led does not blink signalling no transmissions are happening and instead I notice the red LED toggling telling me that there is an error. I went into the tos/types directory and opened message.h ,here I changed message length and set it to 56 from 28 as follows:
ifndef __MESSAGE_H__
#define __MESSAGE_H__
#include "platform_message.h"
#ifndef TOSH_DATA_LENGTH
#define TOSH_DATA_LENGTH 56
#endif
#ifndef TOS_BCAST_ADDR
#define TOS_BCAST_ADDR 0xFFFF
#endif
typedef nx_struct message_t {
nx_uint8_t header[sizeof(message_header_t)];
nx_uint8_t data[TOSH_DATA_LENGTH];
nx_uint8_t footer[sizeof(message_footer_t)];
nx_uint8_t metadata[sizeof(message_metadata_t)];
} message_t;
After making the above change I downloaded the Oscilloscope application onto my mote,yet the problem persists,am I missing something? After making the change to message_t, do I need to do compile something before i download the code?

Arduino: error: 'abs' was not declared in this scope

I'm working on an arduino library needing the abs() function:
#include <math.h>
normTransFreq1 = abs(1.0);
Error: 'abs' was not declared in this scope
As math.h is already included in the cpp I'm entirely unsure how to fix this problem. A new install of arduino 1.5.2 didn't help.
Just found the solution:
Including math.h is not needed for the library. Instead, Arduino.h should be included by adding the following to the header file:
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

windows version of R package much slower than linux version

I'm running ubuntu, 64bit. I have this minimal test package that i made to learn how to do these things (I'm following this tutorial, except i also have some c code in the package).
The package build/runs in linux so i set about making it run in windows too.
I followed this answer and used the online windows package builder maintained by Uwe Ligges to get a (working) zip version of my package.
Now, when i install that .zip package on windows (7-64) the small demo code runs slower than the linux version. As in 30 times slower. I doubt the difference is always so large.
I'm wondering what i'm doing wrong and how i can fix this gap.
EDIT:
this is the source code (it's a minimal working example):
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <fstream>
#include <iostream>
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include <vector>
#include <Eigen/Dense>
#include <Eigen/LU>
#include <Eigen/SVD>
using namespace std;
using namespace Eigen;
using Eigen::MatrixXf;
using Eigen::VectorXf;
float median(VectorXf& x) {
int n=x.rows();
int half=(n+1)/2;
half--;
float med;
nth_element(x.data(),x.data()+half,x.data()+x.size());
if((n%2)==1){
med=x(half);
} else {
float tmp0=x(half);
float tmp1=x.segment(half+1,half-1).minCoeff();
med=0.5*(tmp0+tmp1);
}
return med;
}
VectorXf fx01(MatrixXf& x){
int p=x.cols();
int n=x.rows();
VectorXf Recept(n);
VectorXf Result(p);
for(int i=0;i<p;i++){
Recept=x.col(i);
Result(i)=median(Recept);
}
return Result;
}
extern "C"{
void mse(int* n,int* p,float* x,float* medsout){
MatrixXf x_cen=Map<MatrixXf>(x,*n,*p);
VectorXf MedsOut=fx01(x_cen);
Map<VectorXf>(medsout,*p)=MedsOut.array();
}
}
EDIT2:
Following cbeleites suggestion i ran the code multiple times. Doing this I found
a strange thing: the function's timing are actually the same as linux except when
i call apply() before calling my function --I was always comparing the timing
of the colwise median my pack computes to the timing of doing apply(X,2,median)--
Ok, problem solved. For now. Still i'm curious now: why would a good old fashioned
call to apply() (on a huge matrix X) wreck things so badly (system.time went from
90sec to 3sec)?
One possibility that comes to my mind where calculations on different machines can differ about is the BLAS (if there are linear algebra calculations in the example).
Do you have an optimized BLAS installed on Ubuntu (e.g. libopenblas) but not on Windows?

How to include an already written library to a custom library in Arduino

I'm creating a new library to control the keypad and LCD together. Most of the code seems to compile, but when it reaches the line where I define the LiquidCristal variable, it says:
'LiquidCrystal' does not name a type when creating a custom library
This is the extract of content of my LCDKeypad.h
// Include types & constants of Wiring core API
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#include "WConstants.h"
#endif
// Include LCD library
#include <LiquidCrystal.h>
The error is in this line:
private:
LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 ); // <<-- Error
Alright, I was reading a lot and I found a very interesting article about this subject:
Including multiple libraries
It says that the compiler does not search for libraries that are not included in the sketch file. The way to hack this is to force the compiler to link them before loading your libraries, including, in my case LiquidCrystal.h in the sketch.
Let's say my library "LCDkeypad" requires LiquidCrystal.
My main program (sketch) needs to include LiquidCrystal in order to load it for my library "LCDKeypad".
Now, one interesting thing is using forward declaration, so in my LCDKeypad.h I will declare
"Class LiquidCrystal" but not include the library. I will do it in LiquidCrystal.cpp and in the sketch.
I hope this is clear.
There are two ways of doing it
If you are writing your own code Just create header file .h extension and relevant c code as name_c.While adding into main program, you need to specify header file name in double quotes.
code:
#ifndef LCD_H
#define LCD_H
//Declaration of variable /functions
#endif
If you are trying to download from link. Then you need paste the code into D:\arduino\arduino\libraries
Error problem:
overlapping of multiple declaration of variable.
overlapping of library functions

Resources