How can one determine the board type (e.g. Uno vs Nano) of an Arduino at time of compile?
Not to be confused with determining the processor type. As I see examples of this e.g. #if defined(__AVR_ATmega32U4__) ...
I would like a way, similarly, to determine between flavors of Arduino's all using the same processor of ATmega328.
The IDE knows board. So is it possible to access it from some pre-compiler #IF
The Nano has different interrupts vs. the Uno. Hence knowing board type at compile can automate the pin assignments for public libraries.
As you noted, you check off a board target in the development environment so the compiler might know the board. Unfortunately, the IDE does not tell the compiler this information directly. Only the processor type and frequency are passed down.
You can see what the IDE does to compile programs. In the preferences menu, turn on verbose output for compilation. Compile a sketch and you will see something like this:
C:\Apps\arduino-1.0-windows\arduino-1.0\hardware\tools\avr\bin\avr-g++ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=100 -IC:\Apps\arduino-1.0-windows\arduino-1.0\hardware\arduino\cores\arduino -IC:\Apps\arduino-1.0-windows\arduino-1.0\hardware\arduino\variants\standard C:\Users\Jim\AppData\Local\Temp\build4664216036291565363.tmp\Blink.cpp -oC:\Users\Jim\AppData\Local\Temp\build4664216036291565363.tmp\Blink.cpp.o
The -D 's are how the Arduino environment passes defines to the preprocessor. You see that only the CPU speed and arduino version are passed in this way.
The IO pins are defined a different manner: The IDE includes one folder that contains a board specific header file.
This -I argument includes a folder onto the compiler's search path:
-IC:\Apps\arduino-1.0-windows\arduino-1.0\hardware\arduino\variants\standard
In that folder is a pins_arduino.h file that is appropriate for the board you selected.
If you choose a different board, you will see this parameter change.
If you are willing to modify your IDE configuration, you can get what you ask for.
So to get what you want, you just need to get one #define directive.
So here is how to
Step 1. Make your own board type. To make a new board type, see the boards.txt file located in this folder:
...\arduino-1.0\hardware\arduino
The line like this define the include folder (standard in this case):
uno.build.variant=standard
Copy an entire block, changing the name and the folder
myuno.name=My Arduino Uno
...
myuno.build.variant=myunoboard
With this change, when you select this board target, the myunoboard folder will be placed on the compiler path.
Step 2. Make you header that includes your define.
In the folder
...\arduino-1.0\hardware\arduino\variants\myunoboard
make a file pins_arduino.h. In that file
#include "..\standard\pins_arduino.h"
#define BOARD MY_UNO
// and/or this form
#define __BOARD_MY_UNO
Step 3. Repeat for more boards.
This will provide the ability to build your code for different board targets.
Having said this, I wouldn't really recommend this approach. If you are starting to think about creating code that runs across multiple targets, it may be time to move on from the Arduino IDE. If you were using an environment such as Eclipse, you have one project with any number of build configurations. Each build configuration can specify different preprocessor defines for the board target.
I don't think that there is such a thing built into the arduino IDE, but you can always write your own makefile and define such a thing yourself.
http://pragprog.com/magazines/2011-04/advanced-arduino-hacking
If you scroll down to the hello world example, you will see an example makefile, with a BOARD make variable defined and with just a little extra makefile smarts you could invoke make like this:
make BOARD=UNO
or
make BOARD=NANO
to build the sketch for the different boards.
An easy way to do board sniffing is to use a library such as ArduinoManager. With this you can very easily get the board name and features https://github.com/backupbrain/ArduinoBoardManager
It uses the technique described above to reveal lots of information about almost every Arduino board, so it's great for making projects that might get deployed on a lot different environments.
Just download and include in your Arduino project.
#include "ArduinoBoardManager.h"
ArduinoBoardManager arduino = ArduinoBoardManager(); // required if you want to know the board name and specific features
void setup() {
Serial.begin(9600);
Serial.print("Board is compatible with Arduino ");
Serial.println(arduino.BOARD_NAME);
Serial.println("Speed/SRAM/Flash: ");
Serial.print(ArduinoBoardManager::MAX_MHZ);
Serial.println(ArduinoBoardManager::SRAM_SIZE);
Serial.println(ArduinoBoardManager::FLASH_SIZE);
// Board features (multiple serial ports on Mega, for example)
if (arduino.featureExists(ArduinoBoardManager::FEATURE_MULTIPLE_SERIAL)) {
Serial.println("Your board supports multiple serial connections");
}
}
void loop() {
}
The resulting output on Arduino Uno is:
Board is compatible with Arduino UNO
Speed/SRAM/Flash:
16000000
2048
33554432
The process for making this library (including example code) to determine an Arduino board model and version is described in detail on my blog.
Related
I have my own linker and machine code converter.I am using my own assembly instruction for my machine.This machine is a software processor which executes machine code generated by asm to hex converter. Instead of assembly, i wan to use c language now.My question is that how to use LLVM for this purpose.
One approach could be that:
Create one parser which will read .s file (sort of asm file) generated by LLVM IR and map those instruction with my processor specific asm instruction.
I donot want to create linker and asm to machine code converter again.
Is my approach ok? or what could be the better way to do that.
The *.s file you read is not just "sort of asm", it is actually assembler that has already passed some LLVM backend, probably some X86 variant if you have not chosen a different target.
What you really want to do is to make LLVM emit assembly instructions for your own machine instead. This is what Writing an LLVM Backend and similar guides are about.
This is not exactly simple, but I expect that trying to translate some other machine's instruction set (let alone X86) to your own is probably even more difficult, as you would have to emulate each and every detail of a very complex machine.
I would like to know if it is possible to use selective arduino libraries in our AVR projects. For Example: I am using Atmega328 and Atmel studio. I would like to use DS1307 related library file(twi.c and Wire.c source files I guess) in my project. Can we use individual libraries and then include applicable header files in our build? If so where are these libraries located and what is the extension? I saw few articles on building entire arduino project in Atmel studio and I am not interested in that. I want to manage without installing arduino if possible (I can install arduino only to get library if needed). I thought of including source files, but they are in C++ and I started getting error messages when included in C project. Is it possible to do without modifying the source files much?
After searching, i found that
Any 5V microcontroller with I2C built-in can easily use the DS1307.
check also first lines here.
I look quickly at DS1307.c and found it is not using any functions from wire.c
But instead of all that you could get source code for DS1307.c and implement any function begin with i2c by yourself and small modifications for interrupt functions. and you can use it in your code. i downloaded the library from this link.
There are a lot of twi/i2c libraries for avr, you could download most suitable one and rename it's function like the function called from DS1307.c
I've created an Arduino project using the "Adafruit_SSD1306" display library, which works as expected using a Uno board.
A subsequent project needed to use the ESP8266 wifi board, which required a new display library "ESP_SSD1306". I can see from the source this library is derived from the "Adafruit_SSD1306". Everything compiles and works as expected.
However, if I go back and try to rebuild my old project, or any old project, sample etc that references "Adafruit_SSD1306", it will not build, unless I remove the "ESP_SSD1306" library from my "libraries" folder.
The error is:
sketch_aug04b_xxxxxxx.ino:24:30: fatal error: Adafruit_SSD1306.h: No such file or directory
compilation terminated.
Error compiling.
The workaround is to add or remove this library from the libraries folder whenever I switch to non-ESP8266 project and manually add it back when I switch to an ESP8266-based project.
I'm guessing the libraries conflict in some way, but I am hoping there is a better user experience for dealing with this. Some #define or project setting I can use to remove a library from the compilation path (other then the current process, which involves manually removing the library).
Looks like I've found the answer.
Both libraries have the identical name in their library.properties file. This appears to be what is causing the conflict.
The solution was to change the name property of the ESP_SSD1306 library from "Adafruit SSD1306" to "ESP SSD1306":
name=ESP SSD1306
version=1.0.0
author=Adafruit
maintainer=Adafruit
sentence=SSD1306 oled driver library for 'monochrome' 128x64 and 128x32 OLEDs!
paragraph=SSD1306 oled driver library for 'monochrome' 128x64 and 128x32 OLEDs!
category=Display
url=https://github.com/adafruit/Adafruit_SSD1306
architectures=*
I'm wondering how to use Arudino libraries for projects using regular microprocessors, in my case, the ATMega328p. I just have a PDIP processor on a breadboard and I'm not using an Arudino Uno or anything. I also don't want to be use the setup() and loop() Arduino programming environment, but I do want to be able to download and use the EtherCard library, which includes Arduino.h within it.
I'm using Atmel Studio 6.2 on Windows 8.1. I've found this post Using the Arduino libraries for regular AVR code which includes an excellent response, but it's specific (i think) to the linux environment. Has anyone used Arudino libraries for a non-arduino project? If so, how do I properly include them in Atmel Studio?
Thanks in advance for any input you may have.
There are two sets of libraries in Arduino tree. The first general AVR libraries (C) and the second Arduino libs (C++). Arduino extends AVR libraries providing some implicit functionality clock (msec, sec), streams, UART buffered handler etc. Obscure .ino extension file is copied to .cpp with added #include "Arduino.h" line. From my point of view Arduino IDE is wrong idea because it does not use normal make file but it's somehow hardcoded it in java (using only external avr-gcc).
Also "to-be-implemented" loop(), setup() seems like obscure idea introduced by Arduino's main.cpp implicitly linked in every project.
But I'm using both AVR and Arduino libraries and compile with avr-gcc (installed in Arduino tree). I recommend more fresh gcc (4.7 or so unless it causes problem in Avrstudio as Avrstudio 4.19 toolchain using gcc 4.7.x). I have own Makefile and using in Windows XP. You can override also some Arduino functions implemented using attribute ((weak)).
Please connect the ATMEGA USBASP programmer and the ATMEGA328 controller like shown below:
(source: learningaboutelectronics.com)
Then write the ATMEGA Uno firmware code to the controller. It is available over here - https://github.com/arduino/Arduino/tree/master/hardware/arduino/bootloaders/optiboot
Download the 328 hex version over there. These boot loaders will also be available in you computer if you have successfully installed Arduino Sketch IDE. Now write the hex code to the micro-controller using he programmer and from then onwards the controller will work as a arduino uno. Connect the basic crystal and use a breadboard circuit as shown below.
Now you continue your programming and loading on arduino sketch.
I've attempted this myself by compiling the Arduino libraries into their own standalone library and linking to a project in Eclipse, but have had a couple of issues along the way.
Is there a decent guide on how to get this up and running? I've been hard pressed to find one online that actually works... The arduino.cc guide has a couple of flaws in, and troubleshooting drove me insane.
I'm on Mac OS X 10.5 with an Uno board.
Edit: Might be worth noting that most Arduino C guides don't specify the baud rate necessary, just the MCLK frequency (16 MHz). Make sure you've changed this or AVRDude won't understand how to flash your IC.
Other people have had some success using the guide Using Eclipse with Arduino Duemilanove.
Arduino will not work in pure C setup as it requires a C++ compiler. However if you want to include arduino core and other libraries inside your project then read on. Here we can see how to use Arduino Ethernet Library with our code.
STEP BY STEP GUIDE
Get Arduino cores and variants/ files.
Get relevant library, e.g. Arduino Ethernet library
The directory structure is
/
lib/arduino/cores
lib/arduino/variants//pins_arduino.h
lib/arduino/makefile
lib/arduino/build
lib/
The sample make file can be downloaded from:
https://gist.github.com/rjha/b7cda6312552c3e15486
First create Arduino core as a static library. To do so:
$cd to lib/arduino folder
$ make clean
$ make lib
This will create lib/arduino/build/libarduino.a static library file.
Next we goto main project Makefile. There we can define any Arduino library,e.g. Arduino SPI or Arduino Ethernet as a make target that compiles against Arduino core library.
Inside our own make target, we can include Arduino Target that in turns include Arduino core.
For (7) and (8) example, see this gist
https://gist.github.com/rjha/e7b123d3dc4346b5830c
(9) when creating Hex and general linking, link using -larduino and keep the libarduino.a in the search PATH. #see above Gist for an example.
(10) Using this structure you can use any Arduino libraries inside your own code.
Most of the Arduino libraries are a mess dependencies wise and the code quality is also poor. The only benefit is that you can get some ready made libraries to link against your code.